如何让3D游戏角色跳跃不受FPS影响?
解决Unity角色跳跃高度受FPS影响的问题
问题核心原因
你的代码存在两个关键问题导致跳跃高度随FPS波动:
- 速度应用未做时间缩放:
controller.Move(velocity);直接使用速度值,没有乘以时间增量,帧率越高,每秒执行移动的次数越多,角色总位移越大,跳得越高。 - 跳跃初速度公式错误:
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
相关产品推荐
相关产品推荐

