Unity3d中使用Rigidbody时物体碰撞异常如何修复并让碰撞时停止?
解决Unity中物体碰撞穿入/卡顿并实现碰撞停止的问题
问题根源分析
你当前的代码直接在FixedUpdate中累加velocity,这种方式会绕过物理引擎的内置约束,导致物体速度不受物理规则限制,高速运动时极易出现穿模;同时如果碰撞体或刚体设置不当,也会加剧碰撞异常。
具体解决方案
1. 修正速度控制逻辑,避免直接修改Velocity
直接赋值/累加velocity会干扰物理引擎的正常计算,改用符合物理规则的方式控制运动:
- 用
AddForce施加力,让物理引擎处理速度变化 - 添加最大速度限制,防止物体无限加速导致穿模
修改后的速度控制代码:
[SerializeField] KeyCode keyOne; [SerializeField] KeyCode keyTwo; [SerializeField] Vector3 moveDirection; [SerializeField] float maxSpeed = 5f; // 限制最大速度,避免穿模 [SerializeField] float moveForce = 10f; // 控制推力大小 private Rigidbody rb; private void Awake() { rb = GetComponent<Rigidbody>(); rb.freezeRotation = true; // 冻结旋转,避免碰撞时卡顿 } private void FixedUpdate() { // 用AddForce替代直接修改velocity if (Input.GetKey(keyOne)) { rb.AddForce(moveDirection * moveForce, ForceMode.Force); } if (Input.GetKey(keyTwo)) { rb.AddForce(-moveDirection * moveForce, ForceMode.Force); } // 限制最大速度,防止无限加速 rb.velocity = Vector3.ClampMagnitude(rb.velocity, maxSpeed); if (Input.GetKey(KeyCode.R)) { ResetLevel(); } }
2. 调整刚体与碰撞体的关键设置
确保两个物体的物理组件配置正确:
- 碰撞体设置:如果使用
Mesh Collider,必须勾选Convex选项(非凸网格碰撞体无法正确参与物理碰撞);碰撞体需完全包裹物体模型,避免偏移或尺寸过小。 - 刚体设置:
- 将
Collision Detection设置为Continuous Dynamic(高速运动物体必备,减少穿模概率) - 勾选
Freeze Rotation(不需要旋转的话,避免碰撞时旋转导致卡顿) - 确保两个物体的
Mass一致,且Drag不为0(防止无限加速) - 不要勾选
Is Kinematic(运动物体需保留物理交互)
- 将
3. 添加碰撞时强制停止的逻辑
在物体脚本中实现OnCollisionEnter事件,碰撞触发时直接停止双方的运动:
private void OnCollisionEnter(Collision collision) { // 可通过标签筛选目标碰撞对象(提前给碰撞物体添加对应标签) if (collision.gameObject.CompareTag("CollidableObject")) { // 停止当前物体的移动与旋转 rb.velocity = Vector3.zero; rb.angularVelocity = Vector3.zero; // 停止碰撞对象的移动与旋转 Rigidbody otherRb = collision.gameObject.GetComponent<Rigidbody>(); if (otherRb != null) { otherRb.velocity = Vector3.zero; otherRb.angularVelocity = Vector3.zero; } } }
额外排查点
- 检查场景中是否存在其他脚本修改物体位置/速度,导致物理逻辑冲突
- 确保
Fixed Timestep(Edit > Project Settings > Time)设置合理,建议保持默认的0.02秒,避免物理帧间隔过大
内容的提问来源于stack exchange,提问作者user20368131
相关产品推荐
相关产品推荐

