Hey guys, destroying my player when it collides with an obstacle, but I keep getting this error - “MissingReferenceException: The object of type ‘GameObject’ has been destroyed but you are still trying to access it”
It says I should check if it is null, so I tried it like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCollision : MonoBehaviour {
public PlayerMovement Movement;
public Rigidbody rb;
public GameObject explosion;
public void OnCollisionEnter(Collision collisioninfo)
{
if (collisioninfo.collider.tag == "Obstacle")
{
if (gameObject != null)
{
Destroy(gameObject);
}
FindObjectOfType<EndGame>().gameover();
}
Instantiate(explosion, transform.position, transform.rotation);
}
Hasn’t fixed the error and I’m still a little bit confused about how null should work within the context of my script. Would appreciate any help/explanations on this!
if you destroy the game object you cannot access its transform position afterwards.
So, perhaps you should instantiate the explosion before destroying the game object
Also do the game over before, too.
Hey! Thanks for reply!
So gave that a go but still getting the error message
Here is current script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCollision : MonoBehaviour {
public PlayerMovement Movement;
public Rigidbody rb;
public GameObject explosion;
public void OnCollisionEnter(Collision collisioninfo)
{
if (collisioninfo.collider.tag == "Obstacle")
{
FindObjectOfType<EndGame>().gameover();
Instantiate(explosion, transform.position, transform.rotation);
if (gameObject != null)
{
Destroy(gameObject);
}
}
}
}
did I write it wrong? Also my explosion isn’t happening directly ontop of the player (always slightly to the side) - do you know how I might fix this?
it might be slightly to the side if the prefab position is slightly off , maybe?
As for why the reference still… are you trying to access this game object from the same script on another object maybe?
If you’re sure this script is where the problem is for the reference, then right at the top of the method, you could do: if(gameObject == null) return;
and remove the other null check later.
So the current setup is that the script for destroying the object (the object is the player), is on the object itself. So whenever the player collides with tag “Obstacle” it blows up.
Should the script for destroying the object (player) be somewhere else?
Ah ok, I see what the problem is now. When my player is destroyed, the camera object and the ‘GuardianTrigger’ trigger object (that tells the obstacle when to move towards the player to attack them) lose their player reference. This doesn’t seem like a problem as when I restart the level, everything is back to normal anyway, but having these errors doesn’t seem like a good thing to keep in the game?
So Error 1 has: UnityEngine.Transform.get_position() (at C:/buildslave/unity/build/artifacts/generation/common/runtime/TransformBindings.gen.cs:7)
The script to my GuardianTrigger is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class obstacleMovement : MonoBehaviour {
public Transform Player;
public NavMeshAgent Agent;
public bool PlayerProximity = false;
public void OnTriggerEnter(Collider other)
{
if (other.tag == "Player")
{
PlayerProximity = true;
}
}
// Update is called once per frame
void Update ()
{
if (PlayerProximity == true)
{
Agent.SetDestination(Player.position);
}
}
}
And Error 2:
Camera.Player.FixedUdate() (at Asets/Scripts/CameraPlayer.cs:19)
My camera follow script is:
using UnityEngine;
using System.Collections;
public class CameraPlayer : MonoBehaviour {
public GameObject target;
public float xOffset, yOffset, zOffset;
public Camera Camera;
// Update is called once per frame
void FixedUpdate ()
{
transform.position = target.transform.position + new Vector3(xOffset, yOffset, zOffset);
transform.LookAt(target.transform.position);
}
}
Do I need to add some kind of ‘null’ into both of these codes? With the camera script, I tried - if (target == null) {return;} within FixedUpdate but that didn’t work.
Guys, read the error carefully… nowhere does it say that gameobject is the variable that’s causing the error. just that the object is of type “GameObject”. As a matter of fact I’m sure the physics system wouldn’t even call OnCollisionEnter on any monobaviour thats attached to a destroying gameobject.
My bet is that the missing reference exception was on the explosion variable on this line.
And if not then on some other GameObject variable, but not gameObject itself. @jwalden , this is precisely why its important to check the line the error happened on. are you at some point directly, or indirectly destroying the explosion?
wouldn’t matter in this script. the gameobject is only flagged to be destroyed, but the call doesn’t go out till the end of the frame, should always be safe to use the tranform before the next frame. DestroyImmeadiate is a different story…
two things with this code, first yes make sure you make your null checks! Its always good to cover your null checks. secondly don’t call this in FixedUpdate, but rather in LateUpdate. The Camera is only going to try and render once per frame and thats shortly after LateUpdate. Theres no point to calling this in FixedUpdate, which in fact might sometimes miss a frame due to how FixedUpdate gets called.
@JoshuaMcKenzie Hey so I tried this on the camera and it fixed the error:
void LateUpdate ()
{
if (target.gameObject != null)
{
transform.position = target.transform.position + new Vector3(xOffset, yOffset, zOffset);
transform.LookAt(target.transform.position);
}
}
PS. did not see your suggestion for camera until checking back on the reply, but I did add in “if(!Player) return;” to the GuardianTrigger and that fixed the second problem