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

Unity中Mathf.MoveTowards(z,2f,Time.deltaTime)失效问题求助

问题分析与解决

核心问题根源

你犯了一个典型的逻辑错误:每一帧都用Input.GetAxis("Vertical")直接覆盖变量z,导致Mathf.MoveTowards的平滑结果根本无法累积。Input.GetAxis返回的是-1到1之间的实时输入值,你刚用MoveTowards算出的平滑值,下一帧就被输入值冲掉了,自然无法向目标值移动。

针对各个异常点的具体解释

  1. Mathf.MoveTowards(z, 2f, Time.deltaTime)无效
    因为z每一帧都被重置为-1~1的输入值,不管你怎么MoveTowards到2,下一秒z又回到输入范围,永远碰不到2。

  2. 目标设为1f时会超出到1.003
    这是浮点数精度的正常现象:当当前值和目标值的差值小于步长Time.deltaTime时,Mathf.MoveTowards会直接将当前值设为目标,但浮点数的二进制存储会带来微小计算误差,加上Time.deltaTime本身是波动的(比如帧间隔不稳定),就会出现极微小的超界。

  3. 乘2或修改Time.deltaTime导致瞬时完成

    • 把z乘以2只是把输入范围扩大到-2~2,但你依然是用输入值直接覆盖z,MoveTowards的结果无法保留,等于没做平滑。
    • 如果把Time.deltaTime换成固定大值,步长会远大于当前值到目标的距离,Mathf.MoveTowards会直接跳到目标,自然变成瞬时完成。

正确的实现方式

你需要拆分两个变量:一个用来接收输入的目标值,另一个用来存储平滑过渡的当前值。示例代码如下:

// 维护一个平滑过渡的当前值
float currentZ = 0f;
// 接收输入的目标值(可按需调整范围)
float targetZ = 0f;

void Update()
{
    // 用输入更新目标值,将原-1~1范围映射到-2~2
    targetZ = Input.GetAxis("Vertical") * 2f;
    // 对currentZ做平滑过渡,每次Update累积结果
    currentZ = Mathf.MoveTowards(currentZ, targetZ, Time.deltaTime * 5f); // 5f为平滑速度,可自行调整
    
    // 可选:限制范围彻底避免浮点数超界
    currentZ = Mathf.Clamp(currentZ, -2f, 2f);
}

额外优化建议

  • 若要严格限制不超界,在MoveTowards后加上Mathf.Clamp是最直接的方法。
  • 若想避免微小的精度波动,可通过Mathf.Approximately判断当前值是否接近目标,接近时直接设为目标:
    if (Mathf.Approximately(currentZ, targetZ))
    {
        currentZ = targetZ;
    }
    else
    {
        currentZ = Mathf.MoveTowards(currentZ, targetZ, Time.deltaTime * 5f);
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 14:10:08