Unity Game 的 SetDestination 和活动 agent/NavMesh 问题

SetDestination and active agent/NavMesh issue with Unity Game

我正在使用 unity 5 开发一款游戏,目前遇到此错误:

"SetDestination" 只能在已放置在 NavMesh 上的活动代理上调用。 UnityEngine.NavMeshAgent:设置目的地(Vector3) EnemyMovement:Update()(位于 Assets/Scripts/Enemy/EnemyMovement.cs:25)

我的 enemyMovement 脚本代码是:

using UnityEngine;
using System.Collections;

public class EnemyMovement : MonoBehaviour
{
Transform player;
PlayerHealth playerHealth;
EnemyHealth enemyHealth;
NavMeshAgent nav;


void Awake ()
{
    player = GameObject.FindGameObjectWithTag ("Player").transform;
    playerHealth = player.GetComponent <PlayerHealth> ();
    enemyHealth = GetComponent <EnemyHealth> ();
    nav = GetComponent <NavMeshAgent> ();
}


void Update ()
{
    if(enemyHealth.currentHealth > 0 && playerHealth.currentHealth > 0)
    {
        nav.SetDestination (player.position);
    }
    else
    {
        nav.enabled = false;
    }
 }
}

现在我知道这里几乎有一个相同的问题:Unity - "SetDestination" can only be called on an active agent that has been placed on a NavMesh. UnityEngine.NavMeshAgent:SetDestination(Vector3)但是,这个问题似乎没有明确的答复,我已经尝试了一些答复,但似乎没有任何效果。我会说我的游戏运行良好。然而,我添加了一个功能,如果玩家按下 'B' 那么所有的敌人都会死在屏幕上。当我按下 'B' 时,敌人死了,但系统 'crashes' 并且我收到了该错误消息。

EnemyManager.cs:

        public void Kill(int InstanceID)
    {
        if (EnemyManager.Instance.EnemyList.ContainsKey(InstanceID))
            EnemyManager.Instance.EnemyList.Remove(InstanceID);
    }

    public void DeathToAll()
    {
        Dictionary<int, Object> TempEnemyList = new Dictionary<int, Object>(EnemyManager.Instance.EnemyList);
        foreach (KeyValuePair<int, Object> kvp in TempEnemyList)
        {
            // kvp.Key;   // = InstanceID
            // kvp.Value; // = GameObject

            GameObject go = (GameObject)kvp.Value;
            go.GetComponent<EnemyHealth>().Death();
        }

    }

Enemyhealth.cs

        public void Death ()
    {
        // The enemy is dead.
        isDead = true;

        // Turn the collider into a trigger so shots can pass through it.
        capsuleCollider.isTrigger = true;

        // Tell the animator that the enemy is dead.
        anim.SetTrigger ("Dead");

        // Change the audio clip of the audio source to the death clip and play it (this will stop the hurt clip playing).
        enemyAudio.clip = deathClip;
        enemyAudio.Play ();

        // Kill the Enemy (remove from EnemyList)
        // Get the game object associated with "this" EneymHealth script
        // Then get the InstanceID of that game object.
        // That is the game object that needs to be killed.
        EnemyManager.Instance.Kill(this.gameObject.GetInstanceID());


    }

这里的问题是,当您在调用 nav.SetDestination() 之前检查是否 enemyHealth.currentHealth > 0 时,当敌人被玩家的能力杀死时,该值不会改变。相反,似乎在敌人身上设置了标志 isDead,而不影响实际生命值。

为了确保 nav.SetDestination() 不会在敌人死亡时被调用(因为此时敌人似乎不再是有效的活动代理),只需在您的 if 语句中添加一个附加条件:

if(enemyHealth.currentHealth > 0 && !enemyHealth.isDead && playerHealth.currentHealth > 0)
{
    nav.SetDestination (player.position);
}

希望对您有所帮助!如果您有任何问题,请告诉我。 (您可能需要制作 isDead public 才能正常工作。)

另一种解决方案是制作 属性 IsDead 其中 returns 是否 enemyHealth.currentHealth > 0,并通过将敌人的生命值设置为 0 来杀死敌人。然后你不需要有一个健康追踪器和一个必须明确设置的单独的 isDead 标志。这更像是一个设计决定,因为它不会影响功能。