MissingReferenceException没有道理

时间:2019-10-29 12:07:17

标签: c# unity3d

我得到MissingReferenceException,但由于我销毁了GameObject,这没有任何意义,但是我再也没有在代码中提及它。

控制台中的整个错误:

  

MissingReferenceException:类型为“ GameObject”的对象为   已销毁,但您仍在尝试访问它。

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

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

对我来说这没有意义,因为没有其他引用currentShips(当然也没有引用obj,因为它是本地的)。我还尝试检查currentShips != null语句中的if,但没有变化。我猜这只是我忽略的一个简单事情,但这就是该网站的目的,对吧?

2 个答案:

答案 0 :(得分:4)

您得到的是NullReferenceException的Unity内置特殊形式,只是在Unity中销毁引用后实际上不是null,但仍存储了一些信息,例如为什么null

因此检查currentShips != null不会执行任何操作,因为异常并非来自此处。可能更像是

Destroy(obj.gameObject);

obj已被摧毁的地方!


凯(Kay)的评论中已经提到了实际问题,而阿德里亚尼(Adriani6)删除的答案中也提到了实际问题:

shipParent.GetComppnentsInChildren<Transform>()

包括Transform对象本身的shipParent组件!

  

返回type 中类型为GameObject 的所有组件或其任何子项。

另外,shipParent的{​​{1}}最有可能是第一个被发现并销毁的东西!因此,在下一次迭代中,所有子Transform也已被标记为已销毁。


您应该使用

obj

foreach (Transform obj in shipParent.transform) { Destroy(obj.gameObject); } 类型的内置枚举迭代器完全符合您的期望:返回所有第一级子级的Transform引用。

答案 1 :(得分:0)

以下代码应该可以工作。销毁对象列表应从最后一项开始。 Foreach不适合此操作,因为它从列表的开头开始。当您销毁几乎一半的对象时,剩余对象的数量将与下一个要销毁的对象的索引不匹配。

    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);
        }
    }