Unity 2020.3.0f1中如何用Physics.Gravity替代固定值实现重力控制
Unity 2020.3 LTS PlayerController 重力替换标准实现
核心原则
不要手动覆盖Rigidbody的Y轴速度(除非主动跳跃等操作),让Unity物理引擎自动处理重力,仅控制X、Z平面的移动。
步骤1:检查Rigidbody基础设置
- 勾选Rigidbody组件的Use Gravity选项
- 设置合理的Mass值(推荐1-2,过小会导致重力效果不明显)
- 保持Drag和Angular Drag为默认值(或根据需求微调)
步骤2:正确实现XZ轴移动(保留物理重力)
直接修改velocity的X、Z分量,保留Y分量由物理系统计算:
public float moveSpeed = 5f; private Rigidbody rb; void Start() { rb = GetComponent<Rigidbody>(); // 确保物理参数正确 rb.useGravity = true; rb.mass = 1f; } void FixedUpdate() { // 获取水平/垂直输入 float horizontalInput = Input.GetAxis("Horizontal"); float verticalInput = Input.GetAxis("Vertical"); // 生成世界空间的移动方向(若需相对相机,可乘以Camera.main.transform.forward/right) Vector3 moveDir = new Vector3(horizontalInput, 0f, verticalInput).normalized; // 构建目标速度:仅修改XZ,保留当前Y轴的物理重力值 Vector3 targetVelocity = moveDir * moveSpeed; targetVelocity.y = rb.velocity.y; rb.velocity = targetVelocity; }
常见问题解决
- 漂浮/下落过慢:检查Rigidbody的Use Gravity是否开启,Mass是否过小;确保在
FixedUpdate(而非Update)中修改velocity,保证物理帧同步。 - 类型不匹配错误:
Physics.Gravity是Vector3类型,无需手动乘以它,只要开启Use Gravity,物理引擎会自动应用重力加速度。 - 为什么单独赋值XZ:如果直接覆盖整个velocity的Y分量,会打断物理引擎的重力计算逻辑,仅控制水平方向才能让重力正常生效。
补充:跳跃功能实现(可选)
如果需要跳跃,仅在触发时主动修改Y轴速度,其余时间保留物理重力:
public float jumpForce = 7f; public LayerMask groundLayer; void FixedUpdate() { // ... 上述移动代码 ... if (Input.GetButtonDown("Jump") && IsGrounded()) { // 直接设置Y轴速度或用AddForce rb.velocity = new Vector3(rb.velocity.x, jumpForce, rb.velocity.z); // 或:rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse); } } // 检测是否在地面 bool IsGrounded() { return Physics.Raycast(transform.position, Vector3.down, 0.1f, groundLayer); }
内容的提问来源于stack exchange,提问作者Wolfpack'08
相关产品推荐
相关产品推荐

