我的敌人NavMeshAgent AI遇到了问题,首先它会搜索标记为“Defenses”的GameObject,然后根据防御与敌人的距离设置第一个目的地,当防御被摧毁时,数组值会增加一,并将目的地更改为下一个防御。
我的问题是,玩家可以在游戏过程中创建(实例化)新的防御,当所有防御都被摧毁时,我的敌人会变得疯狂,因此,我需要一种方法将这些新防御添加到我的数组中,下面是我的敌人脚本。
public class NavMeshEnemy : MonoBehaviour { [Header("References", order = 0)] [SerializeField] NavMeshAgent enemyAgent; [Space(10)] [SerializeField] GameObject[] destinations; [Space(10)] [SerializeField] float distanceObjects; [SerializeField] int arrayElements = 0; void Awake() { enemyAgent = GetComponent<NavMeshAgent>(); destinations = GameObject.FindGameObjectsWithTag("Defenses"); } void Start() { destinations = destinations.OrderBy((d) => (d.transform.position - this.transform.position).sqrMagnitude).ToArray(); } void Update() { distanceObjects = Vector3.Distance(this.transform.position, destinations[arrayElements].transform.position); enemyAgent.destination = destinations[arrayElements].transform.position; CheckArray(); } void CheckArray() { if (destinations[arrayElements].gameObject.activeInHierarchy == false) { if (arrayElements < destinations.Length - 1) { arrayElements++; enemyAgent.destination = destinations[arrayElements].transform.position; } else { arrayElements = 0; } } } }
感谢阅读! 🙂
回答:
我更倾向于在你的预制件上实现一个带有static
列表的组件,例如
public class NavMeshDestination : MonoBehaviour{ public static HashSet<Transform> existingDestinations = new HashSet<Transform>(); private void Awake() { if(!existingDestinations.Contains(this)) existingDestinations.Add(this); } private void OnDestroy() { if(existingDestinations.Contains(this)) existingDestinations.Remove(this); }}
然后不使用标签,而是简单地执行
public class NavMeshEnemy : MonoBehaviour{ [Header("References", order = 0)] [SerializeField] NavMeshAgent enemyAgent; [Space(10)] [SerializeField] float distanceObjects; [SerializeField] int arrayElements = 0; void Awake() { if(!enemyAgent) enemyAgent = GetComponent<NavMeshAgent>(); } void Update() { destinations = NavMeshDestination.existingDestinations.OrderBy(d => (d.transform.position - this.transform.position).sqrMagnitude).ToArray(); distanceObjects = Vector3.Distance(this.transform.position, destinations[arrayElements].transform.position); enemyAgent.destination = destinations[arrayElements].transform.position; CheckArray(); } void CheckArray() { if (destinations[arrayElements].gameObject.activeInHierarchy == false) { if (arrayElements < destinations.Length - 1) { arrayElements++; enemyAgent.destination = destinations[arrayElements].transform.position; } else { arrayElements = 0; } } }}
然而,请注意,这仍然无法解决没有可用目的地的问题。因此,如果数组为空,你可能应该停止执行,如下所示
if(NavMeshDestination.existingDestinations.Count == 0){ // 停止enemyAgent return;}