Tomek Śmigielski
Tomek Śmigielski

Reputation: 75

MissingReferenceException makes no sense

I am getting MissingReferenceException but it doesnt make sense, since I am destroying a GameObject, but I never mention it in the code again.

The whole error in console:

MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it.

Transform[] currentShips = shipParent.GetComponentsInChildren<Transform>();

if (currentShips.Length > 0)
{
    foreach (Transform obj in currentShips)
    {
        Destroy(obj.gameObject);
    }
}

It doesn't make sense to me since there is no other references to currentShips (and also of course not to obj, since its local). I also tried checking if currentShips != null in the if statement, but no change. I am guessing its just a little simple thing I am overlooking, but thats what this site is made for, right?

Upvotes: 2

Views: 1242

Answers (2)

derHugo
derHugo

Reputation: 90659

What you get here is a Unity built-in special form of a NullReferenceException just that after destroying the reference in Unity isn't actually null but still stores some information e.g. the why it is null.

So checking currentShips != null doesn't do anything since the exception doesn't come from here. It is probably rather in the line

Destroy(obj.gameObject);

where obj was already destroyed!


The actual issue was mentioned already in the comments by Kay and also on the deleted answer by Adriani6:

shipParent.GetComppnentsInChildren<Transform>()

includes the Transform component of the shipParent object itself!!

Returns all components of Type type in the GameObject or any of its children.

Additionally it is most likely that the shipParent's Transform is the very first one to be found and destroyed! So in the next iteration all child obj are already also marked as destroyed.


Instead you should use

foreach (Transform obj in shipParent.transform)
{
    Destroy(obj.gameObject);
}

this built-in enumeration iterator for the Transform type does exactly what you would expect: Returns all first level children's Transform reference.

Upvotes: 5

Halil Ozdemir
Halil Ozdemir

Reputation: 81

The following code should work. Destroying a list of objects should start from the last item. Foreach is not suitable for this, because it starts from the beginning of the list. When you destroy almost half of the objects, the count of the remaining objects won't match the index of the next object to be destroyed.

    Transform[] currentShips = shipParent.GetComponentsInChildren<Transform>();

    if (currentShips.Length > 0)
    {
        int objCount = currentShips.Length;
        for (int i = objCount - 1; i >= 0; i--)
        {
            Destroy(currentShips[i].gameObject);
        }
    }

Upvotes: 0

Related Questions