You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MoveTowards无法到达点击点,求代码排查及Update/FixedUpdate选择建议

问题排查与解答

代码问题分析与修复

你的代码出现瞬移+无法到达目标的核心原因是:Vector3.MoveTowards只在鼠标点击的那一帧(Input.GetMouseButtonDown(0)触发瞬间)执行了一次,而非每帧持续执行移动逻辑,导致物体只动了一小段就停住,看起来像瞬移,自然也到不了目标点。

修复后的代码如下:

using UnityEngine;

namespace Assets.Scripts
{
    public class MoveToTarget : MonoBehaviour
    {
        public GameObject player;
        // 存储目标位置,供每帧移动逻辑读取
        private Vector3 _targetPos;
        // 标记是否需要执行移动
        private bool _isMoving = false;
        // 可在Inspector面板调整的移动速度
        public float moveSpeed = 5f;

        private void Awake()
        {
            player = GameObject.Find("player");
            // 初始化目标位置为玩家当前位置
            _targetPos = player.transform.position;
        }

        private void Update()
        {
            // 仅在鼠标点击时更新目标位置
            if (Input.GetMouseButtonDown(0))
            {
                // 转换屏幕坐标到世界坐标,Z轴取相机与玩家的距离保证坐标正确
                Vector3 clickPoint = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,
                    Input.mousePosition.y, Camera.main.transform.position.z - player.transform.position.z));
                
                // 固定Y轴,仅做水平移动
                _targetPos = new Vector3(clickPoint.x, player.transform.position.y, 0);
                _isMoving = true;
            }

            // 每帧执行移动逻辑,直到到达目标点
            if (_isMoving)
            {
                player.transform.position = Vector3.MoveTowards(player.transform.position, _targetPos, moveSpeed * Time.deltaTime);
                
                // 用微小距离阈值判断是否到达目标(避免浮点数精度问题)
                if (Vector3.Distance(player.transform.position, _targetPos) < 0.01f)
                {
                    player.transform.position = _targetPos;
                    _isMoving = false;
                    // 此处可添加停止行走动画的逻辑
                }
                else
                {
                    // 此处可添加播放行走动画的逻辑
                }
            }
        }
    }
}

关键修复点:

  • 新增_targetPos和_isMoving变量,让移动逻辑能脱离点击事件,在每帧持续执行
  • 将移动逻辑从点击分支中独立出来,确保每帧都处理位置更新
  • 增加到达目标点的判断逻辑,避免因浮点数精度导致的位置偏差
  • 把移动速度设为可配置的公共变量,方便调试调整

Update 与 FixedUpdate 选择说明

  • 鼠标/键盘输入必须放在Update()中处理:FixedUpdate()是固定时间间隔执行(默认0.02秒一次),若帧率高于固定步长,会出现多次FixedUpdate对应一次Update,导致输入事件丢失;若帧率低于固定步长,又会出现输入响应延迟,只有Update能稳定捕获输入事件。
  • 移动逻辑的选择:
    • 像你现在直接修改Transform的场景,移动逻辑放在Update()即可,和输入逻辑统一,代码更简洁。
    • 若使用Rigidbody组件(需要物理碰撞、重力等效果),则移动逻辑要放在FixedUpdate()里(物理引擎更新与FixedUpdate同步),此时可在Update里捕获输入,把目标位置或移动方向传递给FixedUpdate处理。

内容的提问来源于stack exchange,提问作者md3sla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 09:45:51