Sean Carey
Sean Carey

Reputation: 807

MissingReferenceExcepetion after deleting an object

I have the following script

 using System.Collections;
 using UnityEngine;

public class Bullet : MonoBehaviour
{

[SerializeField]
private float _speed;

private IEnumerator ShootAt(Vector3 target)
{
    while (transform.position != target)
    {
        yield return null;
        transform.localPosition = Vector3.MoveTowards(transform.localPosition, target, _speed * Time.deltaTime);
    }
}

private void OnTriggerEnter2D(Collider2D other)
{
    if (other.tag == "Animal")
    {
        Destroy(gameObject);
    }
}

}

After the bullet hits the animal and gets destroyed, I get the following error: MissingReferenceException: The object of type 'Bullet' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object.

The error is referring to the while loop in my code. I guess it's still running that loop because the condition to stop it hasn't been met yet

  while(transform.position != target)

I tried adding a second condition to stop that loop, like

  while(transform.position != target || gameObject != null)

but that doesn't seem to work. Any help would be more than appreciated.

Upvotes: 0

Views: 223

Answers (1)

lase
lase

Reputation: 2634

Apart from some refactoring like another user suggested in the comments, you could try the same logic you have, but reversed:

while(gameObject != null || transform.position != target)

The || operator will be evaluated in order it is written, so in your case the transform.position is still being evaluated before your null check.

Also, you could consider using StopCoroutine prior to calling Destroy on your object.

Finally, as I've also personally had trouble with such a case (perhaps related to this behavior)

The only thing that the C# object has is a pointer to the native object, so Destroy(myGameObject) destroys the native object but the managed object in the C# side still exists, and is destroyed when it's no longer referenced and is collected by the garbage collector.

So you might just consider introducing a isHit member variable and setting it to true upon a successful collision, followed up with your Destroy.

Upvotes: 2

Related Questions