0

我现在正在制作一个游戏,敌人会向玩家发出警报并无限期地追逐他们,直到玩家站在游戏中的“安全盘子”上。当玩家站在这里时,敌人应该回到他们原来的位置。

问题是,每当玩家站在盘子上时,我都会收到空引用异常错误,并且我可以看到控制台中的原始守卫位置已重置为 0,0,0。我假设空引用异常的原因是因为世界原点不在我正在使用的导航网格上,尽管我很容易错了。我似乎无法弄清楚为什么 vector3 值发生了根本变化,因为 guardPosition 变量在 Start 上启动并且再也没有被触及过。

我已经包括了我的enemyAi 类(附加到敌人的脚本)和我的与踩到盘子相关的类。如果还有什么需要包括的,请告诉我。如果有人有任何想法,我们将不胜感激。干杯。

上板后控制台截图

public class EnemyAI : MonoBehaviour
{
    
    DeathHandler dh;

    [SerializeField] Transform target;
    [SerializeField] float chaseRange = 5f;
    [SerializeField] float killRange = 2f;

    [SerializeField] GameObject explosionEffect;

    NavMeshAgent navMeshAgent;
    float distanceToTarget = Mathf.Infinity;
    bool isDead = false;
    bool isAlert = false;

    Vector3 guardPosition;

    void Start()
    {
        GameObject gob;
        gob = GameObject.Find("Player");
        dh = gob.GetComponent<DeathHandler>();

        guardPosition = transform.position;

        navMeshAgent = GetComponent<NavMeshAgent>();
    }

    void Update()
    {
        distanceToTarget = Vector3.Distance(target.position, transform.position);

        print(guardPosition + " guard position during update");

        //alert a dude
        if (distanceToTarget <= chaseRange && !isDead)
        {
            isAlert = true;
        }

        //chase a dude
        if (isAlert == true)
        {
            ChasePlayer();
            print(isAlert);
        }
    }

    public void ChasePlayer()
    {
        navMeshAgent.SetDestination(target.position);

        //explode a dude
        if (distanceToTarget <= killRange)
        {
            Explode();
            dh.KillPlayer();
        }
    }

    public void SetAlertStatus(bool status)
    {
        isAlert = status;
    }

    public void ReturnToPost()
    {
        //isAlert = false;
        print(guardPosition + " guard position after stepping on plate");
        navMeshAgent.SetDestination(guardPosition);
    }    

    void Explode()
    {
        Instantiate(explosionEffect, transform.position, transform.rotation);

        isDead = true;
        Destroy(gameObject);
    }

    void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, chaseRange);
    }
}
public class SafeSpots : MonoBehaviour
{
    
EnemyAI enemyAi;

    

    void Start()
    {
        GameObject gob;
        gob = GameObject.FindGameObjectWithTag("Enemy");
        enemyAi = gob.GetComponent<EnemyAI>();
    }

    public void OnTriggerStay(Collider other)
    {
        if (other.gameObject.tag == "Player")
        {
            

            enemyAi.SetAlertStatus(false);
            enemyAi.ReturnToPost();
        }
    }
}
4

1 回答 1

0

您正在获得一个已禁用的EnemyAI. 相反,使用FindGameObjectsWithTagthen 遍历所有这些并将它们添加EnemyAI到列表中,您可以在必要时对其进行迭代。顺便说一句,最好CompareTag尽可能减少垃圾:

public class SafeSpots : MonoBehaviour
{
    
    List<EnemyAI> enemyAis;

    void Start()
    {
        GameObject[] enemies= GameObject.FindGameObjectsWithTag("Enemy");
        enemyAis = new List<EnemyAI>();
       
        foreach (GameObject enemy in enemies)
        {
            enemyAis.Add(enemy.GetComponent<EnemyAI>());
        }
    }

    public void OnTriggerStay(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            foreach(EnemyAI enemyAi in enemyAis)
            {
                enemyAi.SetAlertStatus(false);
                enemyAi.ReturnToPost();
            }
        }
    }
}
于 2020-12-15T16:54:00.160 回答