Unity中OnCollisionEnter设置Rigidbody.useGravity失效且碰撞偶发失败
问题根因分析
- 核心错误:直接调用
transform.Translate()移动挂载了Rigidbody的物体,该方法会直接修改物体世界坐标,完全绕过Unity物理引擎的碰撞计算流程,你设置的Continuous连续碰撞检测仅对通过Rigidbody API(AddForce、直接赋值velocity等)驱动的物体生效,对手动瞬移的物体无效,偶发碰撞成功只是因为两帧之间的位移量刚好没完全穿过碰撞体,属于巧合。 - 逻辑冲突:你自己手写了一套重力计算逻辑,和Rigidbody原生重力逻辑冲突,且移动逻辑放在LateUpdate执行,相当于每次物理引擎计算完碰撞后,你又把物体瞬移走了,碰撞检测自然无法稳定触发。
- 状态切换逻辑死循环:你仅在
OnCollisionEnter里才关闭手动移动逻辑,本身就要求碰撞检测先触发才能停止瞬移,完全卡死了正常碰撞的触发条件。
修复方案
完全丢弃transform.Translate移动逻辑,所有位移交给物理引擎处理,仅在初始化时给炸弹赋值初速度,后续重力、碰撞检测都用Unity原生物理逻辑实现即可,修改后代码如下:
using UnityEngine; public class BombBehavior : MonoBehaviour { [SerializeField] float ExplosionForce = 300; [SerializeField] float ExplosionRadius; [SerializeField] float LaunchForceX; [SerializeField] float LaunchForceY; [SerializeField] float Delay; float countdown; Rigidbody rigidbodyy; Player player; bool HasExploded = false; void Start() { rigidbodyy = GetComponent<Rigidbody>(); player = Player.p; // 直接通过刚体API设置初速度,所有位移交给物理引擎处理 float finalX = transform.position.x > player.transform.position.x ? LaunchForceX : -LaunchForceX; rigidbodyy.velocity = new Vector3(finalX, LaunchForceY, 0); // 直接开启原生重力,不用手写模拟 rigidbodyy.useGravity = true; countdown = Delay; } private void Update() { countdown -= Time.deltaTime; if (countdown <= 0 && !HasExploded) { ExplodeNearEnemy(); } } private void ExplodeNearEnemy() { HasExploded = true; Collider[] colliders = Physics.OverlapSphere(transform.position, ExplosionRadius); foreach (Collider collider in colliders) { if (collider.gameObject.CompareTag("Enemy")) { Rigidbody enemyRB = collider.GetComponent<Rigidbody>(); if (enemyRB != null) { enemyRB.useGravity = true; enemyRB.AddExplosionForce(ExplosionForce, transform.position, ExplosionRadius); Destroy(enemyRB.gameObject,1); } } } Destroy(gameObject); } private void OnCollisionEnter(Collision collision) { // 此处可扩展碰撞后的自定义逻辑,比如碰地面直接爆炸 } }
补充优化设置
- 炸弹优先用SphereCollider、CapsuleCollider等简单碰撞体,比ProBuilder生成的网格碰撞体检测效率高、漏检率低,如果必须用网格碰撞体请勾选Convex选项
- 如果炸弹飞行速度很快,可以把碰撞检测模式改成Continuous Dynamic,对高速移动的小物体碰撞检测更精准
- 地板的碰撞体不要用MeshCollider,优先用BoxCollider等简单碰撞体,ProBuilder生成的复杂MeshCollider会大幅提升漏检概率
内容的提问来源于stack exchange,提问作者Omri Azran
相关产品推荐
相关产品推荐

