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

如何让3D游戏角色跳跃不受FPS影响?

解决Unity角色跳跃高度受FPS影响的问题

问题核心原因

你的代码存在两个关键问题导致跳跃高度随FPS波动:

  1. 速度应用未做时间缩放:controller.Move(velocity);直接使用速度值,没有乘以时间增量,帧率越高,每秒执行移动的次数越多,角色总位移越大,跳得越高。
  2. 跳跃初速度公式错误:Mathf.Sqrt(3 - gravity)不符合物理规律,无法稳定控制跳跃高度。

解决方案

1. 修正速度的时间缩放逻辑

所有基于速度的移动操作必须乘以时间增量(Time.deltaTime或Time.fixedDeltaTime),确保每帧位移与时间挂钩而非帧率。修改移动代码:

controller.Move(velocity * Time.deltaTime);

2. 修正跳跃初速度计算

根据竖直上抛运动的最大高度公式 h = v₀²/(2g),反推得到跳跃初速度公式 v₀ = √(2gh)(g为重力加速度绝对值,h为目标跳跃高度),替换原跳跃速度赋值:

// 示例:目标跳跃高度为3米,可根据需求调整数值
velocity.y = Mathf.Sqrt(2 * Mathf.Abs(gravity) * 3f);

3. 推荐将物理逻辑移至FixedUpdate

Update调用频率随帧率波动,而FixedUpdate以固定时间间隔执行(默认0.02秒/次),更适合处理物理逻辑,进一步避免帧率波动影响。拆分后的完整代码示例:

void Update()
{
    // 输入检测与水平移动
    float posX = Input.GetAxis("Horizontal");
    float posZ = Input.GetAxis("Vertical");
    Vector3 move = transform.right * posX + transform.forward * posZ;
    controller.Move(move * speed * Time.deltaTime);

    // 跳跃触发
    if ((Input.GetMouseButton(0) || Input.GetKey(KeyCode.Return)) && Ground)
    {
        velocity.y = Mathf.Sqrt(2 * Mathf.Abs(gravity) * 3f);
    }
}

void FixedUpdate()
{
    // 地面检测与重力处理
    Ground = Physics.CheckSphere(GroundCheck.position, groundDistance, Groundmask);

    if (Ground && velocity.y < 0)
    {
        velocity.y = -0.5f;
    }

    velocity.y += gravity * Time.fixedDeltaTime;
    controller.Move(velocity * Time.fixedDeltaTime);
}

关键说明

  • 水平移动代码原本已正确使用Time.deltaTime,无需修改;
  • FixedUpdate中使用Time.fixedDeltaTime处理物理,保证重力累加和移动计算的稳定性;
  • 修正后的跳跃初速度公式,让跳跃高度仅由你设定的目标高度和重力决定,彻底脱离帧率影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 13:25:32