首页 > 解决方案 > MissingReferenceException:“攻击者”类型的对象已被破坏,但您仍在尝试访问它

问题描述

我收到上述错误,我尝试使用 debug.log 打印错误所在。我正在创建一种坦克 obj。这会触发一些实例化的 obj。实例化的对象是攻击者。

在更新中,我使用 foreach 循环遍历所有实例化对象。如果找到并且如果对象在射程范围内。

void Update () {


        if (attacker!= null  )
        {
            //Debug.Log("inside att");
            attacker = FindObjectsOfType<Attacker>();
        }

        // fire only if attacker is in range 

        if (IfInRange() && attacker!= null && running)
        {

            faceTowardTarget();
            Fire();
        }


    }
    bool IfInRange()
    {// run through all the instantiated attacker
        foreach (Attacker currentAttacker in attacker)

这工作正常,但上面给出了一些东西。在控制台的最后,循环继续进行,并且 currentAttacker 最终为空。我试图在控制台中打印它。但它不会出现在其他 if 语句中

{   //if attacker is in range

            if (attacker != null )
                {

                    Debug.Log(currentAttacker.GetComponent<Health>().isAlive);

                    if (Vector2.Distance(transform.position, currentAttacker.transform.position) < minDistance)               
                    {

                        attackerPos = currentAttacker.transform;

                        return true;
                    }
                }
                if (currentAttacker == null)
                {
                    Debug.Log("curre Attacker null");
                    running = false;
                    return false;
                }

             }return false;
        }

攻击者有一个简单的健康脚本来处理被射弹击中时的伤害。

Void update()
    {
     if (health <= 0)
            {
**is there any better way to destroy an obj. If i destroy gameObject that error appear and it get stuck in foreach loop**
               // Destroy(gameObject);
                noOfKilled++;
                isAlive = false;
                scoreHolder.addScore(scoreValue);
            }
    }

非常感谢你的帮助。我尝试搜索但无法解决此问题。

标签: c#unity3d2d

解决方案


解决这个问题的快速而肮脏的方法是使用DestroyImmediate函数而不是Destroy函数。使用DestroyImmediate(gameObject)将破坏该帧中的对象并且FindObjectsOfType<Attacker>()找不到它,因此不会在foreach循环中访问它。


正确的方法是List在你的主代码中创建一个来保存实例化的Attacker脚本:

public GameObject attackerPrefab;
public List<Attacker> attacker = new List<Attacker>();

实例化预制件时,Attacker脚本添加到List

//Instantiate
GameObject obj = Instantiate(attackerPrefab);
//Get Attacker component 
Attacker tempAttacker = obj.GetComponent<Attacker>();
//Add Attacker component to List
attacker.Add(tempAttacker);

最后,当你想在你的健康脚本中销毁攻击者对象时,其删除List然后销毁它。通过在销毁之前将其从 中删除List,您将不会访问标记为已销毁的对象。

//Get the script that stores the List of Attacker
Test otherScript = GameObject.Find("NameOfGameObjectYourScriptIsAttachedTo").GetComponent<Test>();
//Remove from the List
otherScript.attacker.Remove(gameObject.GetComponent<Attacker>());
//Now, destroy this gameObject
Destroy(gameObject);

推荐阅读