添加Time.deltaTime后玩家移动异常:下落缓慢且无法跳跃
玩家移动异常:添加Time.deltaTime后下落缓慢、无法跳跃
我用Rigidbody2D实现玩家移动,未添加Time.deltaTime时运行正常,但加上该参数后,左右移动功能正常,却出现下落速度缓慢且无法跳跃的问题。敌人脚本中应用Time.deltaTime可正常工作,不清楚玩家移动使用Rigidbody2D与直接修改transform.position的差异。以下是我的PlayerMovement脚本代码:
using Newtonsoft.Json.Bson; using System; using UnityEngine; using UnityEngine.SceneManagement; public class PlayerMovement : MonoBehaviour { [SerializeField] private float horSpeed; [SerializeField] private float vertSpeed; private Rigidbody2D rb; private Boolean isJumping; private void Start() { rb = GetComponent<Rigidbody2D>(); } private void Update() { // we store the initial velocity, which is a struct. var v = rb.velocity * Time.deltaTime; if (Input.GetKey(KeyCode.Space) && !isJumping) { vf.y = vertSpeed; isJumping = true; } if (Input.GetKey(KeyCode.A)) { vf.x = -horSpeed; } if (Input.GetKey(KeyCode.D)) { vf.x = horSpeed; } if (Input.GetKey(KeyCode.S)) { vf.y = -vertSpeed; } rb.velocity = vf; if(Input.GetKey(KeyCode.Escape)) SceneManager.LoadScene(0); } private void OnCollisionEnter2D(Collision2D collision) { isJumping = false; } }
问题分析与修复
1. 核心错误:给Rigidbody2D的Velocity错误乘以Time.deltaTime
Rigidbody2D的velocity属性本身就是每秒位移量(单位:米/秒),Unity物理引擎会自动根据帧率计算每帧的位移,已经内置了时间适配逻辑。你给velocity乘以Time.deltaTime,相当于把"每秒速度"改成了"每帧位移",数值被缩小了几十倍(60帧下Time.deltaTime约为0.016),自然会导致下落、跳跃速度变得极慢。
2. Rigidbody2D vs 直接修改transform.position的差异
- 直接改transform.position:完全绕过物理引擎,强制修改物体坐标,必须手动乘
Time.deltaTime保证不同帧率下移动速度一致,否则帧率越高移动越快。 - 用Rigidbody2D.velocity:交给物理引擎处理移动,引擎会自动处理帧率、碰撞、重力等物理效果,不需要额外添加
Time.deltaTime。
3. 脚本其他问题修正
- 变量名笔误:定义了
v但全程用vf,导致逻辑混乱; - 水平移动未重置速度:松开A/D键后玩家会持续移动,需要在无输入时把x速度设为0;
- 跳跃建议用
GetKeyDown:GetKey会持续触发,导致按住空格一直跳; - 下落优先交给重力:除非需要快速下落功能,否则不用S键强制设置向下速度。
修正后的完整代码
using UnityEngine; using UnityEngine.SceneManagement; public class PlayerMovement : MonoBehaviour { [SerializeField] private float horSpeed; [SerializeField] private float jumpForce; private Rigidbody2D rb; private bool isJumping; private void Start() { rb = GetComponent<Rigidbody2D>(); } private void Update() { Vector2 currentVelocity = rb.velocity; // 水平移动处理 float horizontalInput = 0; if (Input.GetKey(KeyCode.A)) { horizontalInput = -horSpeed; } else if (Input.GetKey(KeyCode.D)) { horizontalInput = horSpeed; } currentVelocity.x = horizontalInput; // 跳跃处理 if (Input.GetKeyDown(KeyCode.Space) && !isJumping) { currentVelocity.y = jumpForce; isJumping = true; } // 可选:快速下落功能 if (Input.GetKey(KeyCode.S)) { currentVelocity.y = -jumpForce; } rb.velocity = currentVelocity; // 返回主菜单 if (Input.GetKey(KeyCode.Escape)) { SceneManager.LoadScene(0); } } private void OnCollisionEnter2D(Collision2D collision) { // 仅碰到地面时重置跳跃状态(需给地面添加"Ground"标签) if (collision.gameObject.CompareTag("Ground")) { isJumping = false; } } }
内容的提问来源于stack exchange,提问作者Dom Sendall
相关产品推荐
相关产品推荐

