Unity敌人AI到达定点即停止,如何修改实现非追逐时持续移动?
你的敌人停止移动的核心问题有两个:
- 初始状态没有设置任何移动目标,敌人开局就会静止
- 非追逐状态下,仅当敌人完全到达当前目标后才尝试生成新随机点,一旦
RandomPoint函数找不到有效NavMesh点(返回false),敌人就会失去目标停住
以下是修改后的完整代码,能让敌人在非追逐时持续随机移动:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; public class StalkerAI : MonoBehaviour { public NavMeshAgent agent; public Transform Player; public float range; // 随机移动范围半径 public Transform centrePoint; // 随机移动区域的中心点 // 如果不需要指定区域,可以把centrePoint设为敌人自身的transform void Start() { agent = GetComponent<NavMeshAgent>(); // 初始化时立即生成第一个随机目标,避免开局静止 SetRandomDestination(); } void Update() { float distVal = 5.0f; float dist = Vector3.Distance(transform.position, Player.position); if (dist <= distVal) { // 追逐玩家 agent.SetDestination(Player.position); } else { // 检查是否已到达当前目标,且没有正在规划的路径 if (!agent.pathPending && agent.remainingDistance <= agent.stoppingDistance) { // 生成新的随机目标 SetRandomDestination(); } } } // 封装随机目标生成逻辑,确保能找到有效点 void SetRandomDestination() { Vector3 point; // 最多尝试5次找有效NavMesh点,避免单次失败导致停止 for (int i = 0; i < 5; i++) { if (RandomPoint(centrePoint.position, range, out point)) { Debug.DrawRay(point, Vector3.up, Color.blue, 1.0f); agent.SetDestination(point); return; } } // 如果多次尝试都失败,就以自身位置为中心再试一次(防止区域内无NavMesh) if (RandomPoint(transform.position, range * 0.5f, out point)) { agent.SetDestination(point); } } bool RandomPoint(Vector3 center, float range, out Vector3 result) { Vector3 randomPoint = center + Random.insideUnitSphere * range; NavMeshHit hit; // 增大采样距离,提升找到有效NavMesh点的概率 if (NavMesh.SamplePosition(randomPoint, out hit, 2.0f, NavMesh.AllAreas)) { result = hit.position; return true; } result = Vector3.zero; return false; } }
关键修改说明:
- 初始目标设置:在
Start方法中调用SetRandomDestination,让敌人开局就开始移动 - 封装目标生成逻辑:把随机目标生成的代码抽成独立函数,增加最多5次重试逻辑,避免单次找不到有效点就停止
- 提升采样成功率:调大
NavMesh.SamplePosition的采样距离,更容易在随机点附近找到有效NavMesh区域 - ** fallback 逻辑**:如果多次尝试都找不到有效点,就以敌人自身位置为中心缩小范围再尝试,防止敌人彻底停住
- 优化状态判断:增加
!agent.pathPending判断,避免在路径规划过程中重复设置目标
内容的提问来源于stack exchange,提问作者Mackenzie Digital Design
相关产品推荐
相关产品推荐

