如何检测带有Box Collider的汽车被撞击的侧面?
检测Box Collider被撞击的侧面(Unity)
核心思路是通过碰撞点的局部坐标判断撞击位置:将世界空间的碰撞点转换为汽车的局部空间,对比局部坐标中X/Z轴的绝对值,判断是左右侧还是前后侧碰撞,再根据坐标正负确定具体方向。
基础实现代码
将以下脚本挂载到带Box Collider和Rigidbody的汽车上:
private void OnCollisionEnter(Collision collision) { // 获取首个碰撞接触点 ContactPoint contact = collision.contacts[0]; // 转换为汽车局部坐标 Vector3 localHitPoint = transform.InverseTransformPoint(contact.point); // 假设Y轴向上,X轴对应左右,Z轴对应前后 float absX = Mathf.Abs(localHitPoint.x); float absZ = Mathf.Abs(localHitPoint.z); Rigidbody rb = GetComponent<Rigidbody>(); if (rb == null) return; if (absX > absZ) { // 左右侧碰撞 if (localHitPoint.x > 0) { Debug.Log("右侧被撞击"); rb.AddForce(transform.right * -500f, ForceMode.Impulse); } else { Debug.Log("左侧被撞击"); rb.AddForce(transform.right * 500f, ForceMode.Impulse); } } else { // 前后侧碰撞 if (localHitPoint.z > 0) { Debug.Log("后侧被撞击"); rb.AddForce(transform.forward * -500f, ForceMode.Impulse); } else { Debug.Log("前侧被撞击"); rb.AddForce(transform.forward * 500f, ForceMode.Impulse); } } }
优化方案(更准确)
如果Box Collider未居中,或需要更稳定的判断,可以取所有碰撞点的平均位置,并修正Collider偏移:
private void OnCollisionEnter(Collision collision) { BoxCollider boxCollider = GetComponent<BoxCollider>(); Rigidbody rb = GetComponent<Rigidbody>(); if (boxCollider == null || rb == null) return; // 计算所有碰撞点的平均局部位置 Vector3 averageLocalHit = Vector3.zero; foreach (ContactPoint contact in collision.contacts) { averageLocalHit += transform.InverseTransformPoint(contact.point); } averageLocalHit /= collision.contacts.Length; // 修正Collider的中心偏移 Vector3 adjustedHit = averageLocalHit - boxCollider.center; float absX = Mathf.Abs(adjustedHit.x); float absZ = Mathf.Abs(adjustedHit.z); // 根据碰撞相对速度动态调整力的大小 float forceMultiplier = collision.relativeVelocity.magnitude * 100f; if (absX > absZ) { float direction = adjustedHit.x > 0 ? -1f : 1f; Debug.Log(adjustedHit.x > 0 ? "右侧被撞击" : "左侧被撞击"); rb.AddForce(transform.right * direction * forceMultiplier, ForceMode.Impulse); } else { float direction = adjustedHit.z > 0 ? -1f : 1f; Debug.Log(adjustedHit.z > 0 ? "后侧被撞击" : "前侧被撞击"); rb.AddForce(transform.forward * direction * forceMultiplier, ForceMode.Impulse); } }
注意事项
- 确保汽车对象挂载了Rigidbody组件,否则碰撞事件无法触发;
- 若汽车的坐标系轴方向不同(比如Z轴是左右),只需调整代码中判断的轴即可;
- 力的大小和模式可根据需求修改,
ForceMode.Impulse适合模拟瞬时撞击力。
内容的提问来源于stack exchange,提问作者Mr. Gamer
相关产品推荐
相关产品推荐

