Unity Hack N Slash鼠标点击移动 到达终点如何结束跑步动画
解决方案:鼠标点击寻路到达目标点后自动终止跑步动画
核心原理是直接复用NavMeshAgent自带的路径状态属性做判断,不需要自行计算坐标距离,能避免浮点误差、停止距离不匹配导致的判断失效问题。
现有代码的问题
你目前仅在鼠标点击触发时将Isrunning参数设为true,缺少逐帧检测寻路状态、到达目标后重置动画参数的逻辑,所以跑步动画会持续循环。另外原有逻辑把动画触发写在射线检测外层,点击到无碰撞区域(比如天空盒)时也会误触发跑步动画。
判断到达目标的必要条件
需要同时满足以下3个条件,才能判定角色已经到达终点,避免路径计算中、卡障碍物时的误判:
- 路径计算完成:
agent.pathPending == false,防止刚点击鼠标、路径还没生成时就误判为到达 - 剩余寻路距离小于等于Agent的停止距离:
agent.remainingDistance <= agent.stoppingDistance,适配你在NavMeshAgent组件上设置的停止距离参数,不用硬编码0值 - Agent无有效路径或当前速度为0:
!agent.hasPath || agent.velocity.sqrMagnitude == 0f,规避角色被障碍物卡住、剩余距离看起来很近但实际到不了的情况
修正后的完整代码
using UnityEngine; using UnityEngine.AI; public class PlayerMouseMovement : MonoBehaviour { Camera cam; Animator animator; NavMeshAgent agent; private void Start() { animator = GetComponent<Animator>(); // 直接调用Camera.main查找主相机,比GameObject.Find性能更稳定 cam = Camera.main; agent = GetComponent<NavMeshAgent>(); // 可根据角色模型碰撞体大小调整停止距离,避免到点穿模 agent.stoppingDistance = 0.1f; } private void Update() { // 逐帧检测寻路状态,判断是否到达终点 if (!agent.pathPending && agent.remainingDistance <= agent.stoppingDistance) { if (!agent.hasPath || agent.velocity.sqrMagnitude == 0f) { animator.SetBool("Isrunning", false); } } // 鼠标左键点击寻路逻辑 if (Input.GetMouseButtonDown(0)) { Ray ray = cam.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out RaycastHit hit)) { // 只有射线检测到有效碰撞点、成功设置目的地后,才触发跑步动画 agent.SetDestination(hit.point); animator.SetBool("Isrunning", true); } } } }
可选优化提示
- 生产环境建议直接在Inspector面板拖入相机、组件引用,完全替代运行时查找逻辑,减少性能开销和空引用报错概率
- 如果使用根动画控制角色移动,记得把NavMeshAgent的
updatePosition和updateRotation参数匹配你的动画逻辑,避免出现滑步 - 如果出现到点后动画偶尔延迟1帧切换的情况,可以把距离判断阈值加0.05f的容错值,适配浮点数计算误差,即改成
agent.remainingDistance <= agent.stoppingDistance + 0.05f
内容的提问来源于stack exchange,提问作者Dewicki_
相关产品推荐
相关产品推荐

