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
标志。这更像是一个设计决定,因为它不会影响功能。
我正在使用 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
标志。这更像是一个设计决定,因为它不会影响功能。