AI巡逻功能原型运行正常,使用预制体实例化后敌人卡在首个巡逻点
问题原因分析
- 巡逻点引用失效:将场景内的敌人制作为Prefab时,脚本中
patrolPoints列表存储的是当前场景内的Transform对象引用,Prefab本身无法持久化存储场景专属对象的引用。当你将Prefab重新拖入场景实例化后,patrolPoints列表会出现空引用或全部指向无效对象的问题,导致巡逻逻辑判断异常,敌人无法切换到下一个巡逻点。 - 浮点数精度判断错误:代码中使用
enemy.transform.position != patrolPoints[patrolCounter].position判断是否到达巡逻点,浮点数运算本身存在精度误差,Prefab实例化后坐标可能存在肉眼不可见的微小偏移,导致永远无法满足相等条件,patrolCounter不会累加,敌人卡在第一个巡逻点。 - 变量未初始化:
target变量如果没有在Awake或Start生命周期中赋值,Prefab实例化后初始target值可能和第一个巡逻点坐标不匹配,导致逻辑异常。
解决方案
- 修复巡逻点引用逻辑
二选一即可:
- 方案A:在场景内单独创建一个全局巡逻路径管理对象,挂载专属脚本存储对应路径的巡逻点列表,敌人脚本在
Start生命周期主动从管理对象获取巡逻点列表,避免Prefab需要持有场景对象引用。 - 方案B:给所有巡逻点统一设置专属标签,敌人脚本在
Start生命周期通过标签查找当前场景内的巡逻点,按顺序赋值给patrolPoints列表。
- 修复巡逻点引用逻辑
- 优化巡逻点到达判定逻辑
替换原有的坐标相等判断为距离阈值判断,适配浮点数精度误差,修改后的代码如下:
private void Patrol() { // 防止巡逻点为空导致逻辑报错 if (patrolPoints == null || patrolPoints.Count == 0) return; if (patrolCounter < patrolPoints.Count) { // 用0.1f作为误差阈值,可根据实际移动速度调整 if (Vector2.Distance(enemy.transform.position, patrolPoints[patrolCounter].position) > 0.1f) { target = patrolPoints[patrolCounter].position; } else { patrolCounter++; } } else { patrolCounter = 0; } enemy.transform.position = Vector2.MoveTowards(enemy.transform.position, target, step); }- 优化巡逻点到达判定逻辑
- 增加变量初始化逻辑
在脚本的Start方法中添加初始化代码,确保第一次运行时target被正确赋值:
private void Start() { if (patrolPoints != null && patrolPoints.Count > 0) { target = patrolPoints[0].position; } }- 增加变量初始化逻辑
- 实例化后校验参数
将Prefab拖入场景后,手动检查Inspector面板中patrolPoints列表是否存在空引用,列表长度是否和预期巡逻点数量一致。
- 实例化后校验参数
内容的提问来源于stack exchange,提问作者Todd
相关产品推荐
相关产品推荐

