Unity C#角色到达目标点后无法停止问题求助
修复Unity角色到达目标点后绕圈的问题
问题根源分析
原代码中判断角色到达目标的条件过于严苛,!player.hasPath和player.velocity.sqrMagnitude == 0f的组合很难同时满足:
- 当角色接近目标时,NavMeshAgent可能仍持有有效路径(
hasPath为true),导致第一个条件不成立 velocity.sqrMagnitude == 0f要求速度完全为0,而角色在目标点附近微调时会有微小速度,无法触发停止逻辑
具体修复方案
修改Update方法中的停止判断逻辑,简化条件并增加容错阈值:
using UnityEngine; using UnityEngine.AI; public class CharacterMoveScript : MonoBehaviour { public Camera cam; public NavMeshAgent player; public GameObject targetDest; public Animator playerAnimator; private string groundTag = "Ground"; private RaycastHit hit; private bool isMoving = false; void Start() { player = GetComponent<NavMeshAgent>(); // 设置合理的停止距离,避免过近导致角色微调绕圈 player.stoppingDistance = 0.5f; } private void Update() { if (Input.GetMouseButtonDown(0)) { Ray ray = cam.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out hit, Mathf.Infinity)) { if (hit.collider.CompareTag(groundTag)) { player.SetDestination(hit.point); isMoving = true; // 重置停止状态,确保新移动指令生效 player.isStopped = false; } } } UpdateAnimation(); if (isMoving) { // 简化可靠的到达判断逻辑 if (!player.pathPending && player.remainingDistance <= player.stoppingDistance && player.velocity.sqrMagnitude < 0.01f) { isMoving = false; player.isStopped = true; // 清除路径,彻底避免残留路径导致的微小移动 player.ResetPath(); } } } private void UpdateAnimation() { playerAnimator.SetBool("isWalking", isMoving && player.velocity.magnitude > 0.1f); // 调试日志可按需保留 // UnityEngine.Debug.Log("is moving" + isMoving); // UnityEngine.Debug.Log("is stoped" + player.isStopped); // UnityEngine.Debug.Log(player.pathStatus==NavMeshPathStatus.PathComplete); } }
关键修改点说明
- 移除
!player.hasPath判断,改为依赖remainingDistance和velocity的组合,更贴合NavMeshAgent的实际工作逻辑 - 将
player.velocity.sqrMagnitude == 0f改为player.velocity.sqrMagnitude < 0.01f,增加容错空间,允许角色停止前的微小速度波动 - 设置新目标时主动重置
player.isStopped为false,避免上次停止状态干扰新移动指令 - 添加
player.ResetPath()清除残留路径,彻底杜绝路径残留导致的绕圈 - 在
Start中设置合理的stoppingDistance,默认值过小会迫使角色精确对齐目标点,引发不必要的微调
内容的提问来源于stack exchange,提问作者demonjoseph
相关产品推荐
相关产品推荐

