Unity NavMesh与AI代码问题:NPC在地图角落冻结
问题分析与修复方案
先帮你拆解下目前代码里的核心问题,以及对应的解决办法:
一、为什么IsHit函数始终返回true?
你的IsHit函数循环30次,但每次检测的都是同一个点——transform.position + transform.forward * multiplyBy,相当于重复检查同一个位置。只要这个点在可行走区域内,函数就会直接返回true,完全没尝试其他方向。这就是它永远返回true的根本原因。
二、NPC跑到角落冻结的原因
当NPC处于地图角落时,你逃跑逻辑里计算的runTo点大概率在地图外(不可行走区域),而原代码只尝试了这一个方向,找不到可行走点时没有备选逻辑,导致NavMeshAgent没有新的目标点可移动,直接停在原地冻结。
三、具体修复步骤
1. 修复IsHit函数:尝试多方向检测
修改函数逻辑,让它绕NPC旋转生成不同方向的检测点,这样才能找到周围其他可行走区域:
bool IsHit(out Vector3 result) { // 绕Y轴旋转360度,分成30个方向尝试 for (int i = 0; i < 30; i++) { float angle = i * (360f / 30f); // 每个方向间隔12度 Quaternion rotation = Quaternion.Euler(0, angle, 0); // 生成当前尝试的随机方向 Vector3 randomDirection = rotation * (transform.position - player.position).normalized; Vector3 fixedPoint = transform.position + randomDirection * multiplyBy; NavMeshHit hit; if (NavMesh.SamplePosition(fixedPoint, out hit, 10.0f, 1 << NavMesh.GetAreaFromName("Walkable"))) { result = hit.position; return true; } } result = Vector3.zero; return false; }
2. 修复RunFrom函数:移除无效的transform重置逻辑
原代码里先修改NPC旋转计算逃跑方向,然后立刻把位置和旋转改回初始状态,这完全是矛盾操作——等于白计算了方向。而且NavMeshAgent会自动处理移动和旋转,不需要手动修改transform:
public void RunFrom() { // 计算远离玩家的方向(直接用位置差,不用手动旋转transform) Vector3 awayDirection = (transform.position - player.position).normalized; Vector3 runTo = transform.position + awayDirection * multiplyBy; NavMeshHit hit; if(NavMesh.SamplePosition(runTo, out hit, 50, 1 << NavMesh.GetAreaFromName("Walkable"))) { myNMagent.SetDestination(hit.position); } else { Debug.Log("当前逃跑方向不可行,尝试其他方向"); // 调用修复后的IsHit寻找备选点 if(IsHit(out Vector3 validPos)) { myNMagent.SetDestination(validPos); } else { Debug.Log("周围无可行走区域,NPC可能被困"); } } }
3. 优化ISFacing函数(可选)
减少重复的normalized计算,让逻辑更清晰:
private bool ISFacing() { float angleThreshold = 45f; Vector3 playerForward = player.transform.forward.normalized; Vector3 directionToNPC = (transform.position - player.transform.position).normalized; float angleToPlayer = Vector3.Angle(playerForward, directionToNPC); return angleToPlayer < angleThreshold; }
额外建议
- 不要手动修改
transform.position或transform.rotation,NavMeshAgent会自动处理移动和朝向,手动修改容易导致状态冲突。 - 可以给NavMeshAgent加一个
stoppingDistance,避免NPC过度贴近目标点导致卡顿。
内容的提问来源于stack exchange,提问作者user9673893
相关产品推荐
相关产品推荐

