Unity开发中玩家触碰物体后触发自主持续异常移动问题求助
你遇到的这个问题核心是混用了Transform直接操作和Rigidbody物理体系,两者逻辑冲突才会产生碰撞后残留速度、自主漂移的情况。
修复方案
- 首先把所有和物理、位移、旋转相关的逻辑从
Update移到FixedUpdate方法中:Update的执行频率随设备帧率波动,和物理引擎固定的更新频率不同步,直接操作Transform很容易导致物理引擎计算出额外的动量残留。 - 放弃
transform.Translate实现移动,改用Rigidbody自带的位移方法,比如MovePosition或者直接修改velocity,所有操作走Rigidbody的API才能和物理引擎的计算逻辑对齐,不会产生异常的额外速度。 - 直接在Rigidbody组件的Inspector面板勾选
Freeze Rotation下的X、Z轴,不需要在代码里强制修改eulerAngles锁旋转,直接改Transform的旋转同样会和物理引擎的旋转计算发生冲突。 - 补充落地判断的校验逻辑:当前只要发生碰撞就会判定为落地,碰到墙面、其他物体这类非地面对象也会触发跳越判定,建议给地面单独设置专属Layer,碰撞时先判断碰撞对象的Layer再修改
isOnGround状态。
修改后参考代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerController : MonoBehaviour { public float playerSpeed = 3f; private Rigidbody playerRb; public GameObject cameraRotation; // 可以在Inspector面板指定地面的Layer public LayerMask groundLayer; void Start() { playerRb = GetComponent<Rigidbody>(); } float verticalInput; float horizontalInput; bool isOnGround = true; // 输入检测放在Update,避免漏判按键 void Update() { verticalInput = Input.GetAxis("Vertical"); horizontalInput = Input.GetAxis("Horizontal"); if (Input.GetKeyDown(KeyCode.Space) && isOnGround) { playerRb.AddForce(Vector3.up * 10, ForceMode.Impulse); isOnGround = false; } } // 物理相关操作全部放在FixedUpdate private void FixedUpdate() { // 基于相机朝向计算移动方向 Vector3 moveDir = cameraRotation.transform.forward * verticalInput + cameraRotation.transform.right * horizontalInput; moveDir.y = 0; moveDir.Normalize(); // 用Rigidbody做位移,不走Transform playerRb.MovePosition(transform.position + moveDir * playerSpeed * Time.fixedDeltaTime); // 同步玩家朝向到相机Y轴 playerRb.rotation = Quaternion.Euler(0, cameraRotation.transform.eulerAngles.y, 0); } private void OnCollisionEnter(Collision collision) { // 只有碰到地面才判定落地 if (((1 << collision.gameObject.layer) & groundLayer) != 0) { isOnGround = true; } } }
修改完成后重新测试,碰撞后自主漂移的问题基本就会消失。
内容的提问来源于stack exchange,提问作者The Snapped
相关产品推荐
相关产品推荐

