MissingReferenceException:"Attacker"类型的对象已被破坏,但您仍在尝试访问它

use*_*003 1 c# 2d unity-game-engine

我收到上述错误,我尝试使用debug.log打印错误的位置.我正在创造一种坦克obj.哪个实例化了obj.实例化对象是攻击者.

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

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)
Run Code Online (Sandbox Code Playgroud)

这工作正常,但有些时候会给出上面的结果.在控制台的最后,循环继续进行,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;
        }
Run Code Online (Sandbox Code Playgroud)

攻击者拥有一个简单的健康脚本,可以处理受到弹丸击中的伤害.

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);
            }
    }
Run Code Online (Sandbox Code Playgroud)

非常感谢你的帮助.我试过搜索但无法解决这个问题.

Pro*_*mer 5

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


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

public GameObject attackerPrefab;
public List<Attacker> attacker = new List<Attacker>();
Run Code Online (Sandbox Code Playgroud)

当你实例化的预制,添加Attacker脚本到List:

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

最后,当您想要破坏健康脚本中的攻击者对象时,其从中删除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);
Run Code Online (Sandbox Code Playgroud)