MissingReferenceException:销毁移动游戏对象后出错

MissingReferenceException: Error after destroying a moving game object

在我的游戏中,有些物体每隔几秒就会移动一次,而有些则不会。我创建了下面的方法来处理移动对象的移动。

private IEnumerator moveObject(GameObject movingObject, float posX, float duration) {
if(movingObject != null) {
    float elapsedTime = 0;
    Vector3 startPos = movingObject.transform.position;
    Vector3 endpos = new Vector3(posX, objectPositionY, camera.nearClipPlane);//hole.transform.position;

    while(movingObject != null && elapsedTime < duration) {
        movingObject.transform.position = Vector3.Lerp(startPos, endpos, elapsedTime / duration);
        elapsedTime += Time.deltaTime;
        yield return null;
    }
}
}

我还使用以下代码销毁了移动物体:

for (int i = 0; i < holeObjects.Count; i++) {
    Debug.Log ("countingholeobjectindex"+ i );

    if (col.gameObject.Equals (holeObjects [i].getHoleObject ())) {
       Debug.Log ("condition satisfied!" );

       foreach( HoleObjectSetup holeItem in holeObjects )
       {
          if (holeItem.getHoleObjectType () == HoleObjectSetup.HoleObjectType.moving) {
          int holeItemIndex = holeObjects.IndexOf(holeItem);
          holeItem.StopAllCoroutines();
          holeItem.DestroyHoleObject ();

          //holeObjects.RemoveAll(item=>item==null);
          //holeObjects.RemoveAt(holeItemIndex);

       }
    }
}

每当我销毁一个移动对象(主要是在它移动时),我都会收到错误消息

MissingReferenceException: The object of type 'GameObject' 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.

指向行

movingObject.transform.position = Vector3.Lerp(startPos, endpos, elapsedTime / duration);

movingObject方法中(上面提供)。我尝试添加另一个无效检查来包围 while 循环的内容,但这使 Unity3d 没有响应,让我只有强制退出的唯一选择。我该如何解决这个问题?

更新 movingObject 在下面的协程中被调用:

private IEnumerator MovementLogic(GameObject movingObject)
{
    // keep going until deactivated or disabled
    float currentPos = movingObject.transform.position.x;
    while(filledPositions.Contains(currentPos))
    {
        float newPos = getNextPos(currentPos);
                  if(freePositions.Contains(newPos))
            {
                freePositions.Add (currentPos);
                filledPositions.Remove (currentPos);
                freePositions.Remove (newPos);
                filledPositions.Add (newPos);

                yield return moveObject(movingObject, newPos, movementDuration);

                //update positions
                yield return new WaitForSeconds(movementDelay);
                currentPos = newPos;

            }
            else
            {
                // if a valid hole wasn't found, try the other direction next frame
                ReverseDirection();
            }
        }

    yield return null;
    //}
}

更新 2

HoleObjectSetupDestroyHoleObject() 的代码是:

    public void DestroyHoleObject   ()  {
    Destroy (currentHoleObject);
}

    public void createHoleObjectType    (GameObject holeObject, HoleObjectType holeObjectType, Vector3 holeObjectPosition, bool isCollider2DEnabled)    {

    currentHoleObject = (GameObject)Instantiate (holeObject, holeObjectPosition, Quaternion.identity);
    setHoleObjectType (holeObjectType);

}

添加

解决问题
Debug.Log

声明无处不在。需要几秒钟的时间才能找出循环中导致问题的确切点。

其次,

有时,解决这些问题的廉价方法是使用

DestroyImmediate

而不是

Destroy

这可能会给您一个快速修复。

第三。更复杂地了解协程:

类似..

void OnEnable()
 {
 Debug.Log("enable .."); 
 }

void OnDisable()
 {
 StopCoroutine("Whatever");
 .. or perhaps ..
 StopAllCoroutines();
 }

此外,理想情况下你应该 "handle it manually".

考虑一下您要摆脱的对象。

那个class,应该有这样的功能:

void BeingDestroyed()
 {
 .. carefully write your own code here to shut down the object ..
 }

...实际上 在您要销毁它时显式调用

在游戏中添加、销毁东西并不容易。它通常非常复杂。

可能是对象自行销毁:执行任何需要的关闭代码,等待一两帧(如果与您相关),从任何列表中删除,然后 "destroy self"。

你不能只是"leave coroutines alone":你必须手工小心地管理它们。