Unity中同TrafficCar脚本下如何销毁被碰撞的车辆
解决Unity中碰撞车辆仅销毁被撞方的问题
当前代码的核心问题是:两辆挂载TrafficCar脚本的车辆碰撞时,双方的OnCollisionEnter方法都会被触发。比如车辆A碰撞B时,A的脚本会销毁B,同时B的脚本会销毁A,最终导致两车都被销毁。
下面提供几种实用的解决方案:
方法一:通过速度判断被撞车辆
假设主动碰撞的车辆速度更快,被撞车辆速度相对较慢,通过比较两车速度大小,让速度更慢的一方(被撞方)销毁自己:
void OnCollisionEnter(Collision col) { if (col.gameObject.CompareTag(gameObject.tag)) { Rigidbody myRb = GetComponent<Rigidbody>(); Rigidbody otherRb = col.gameObject.GetComponent<Rigidbody>(); // 仅当当前车辆速度小于碰撞车辆时,销毁自己(判定为被撞方) if (myRb.velocity.magnitude < otherRb.velocity.magnitude) { Destroy(gameObject, 1f); // 若使用对象池,替换为回收逻辑: // ObjectPool.Instance.RecycleVehicle(gameObject); } } }
方法二:用标记避免重复销毁
给每个车辆添加一个状态标记,确保同一碰撞事件中只有一方触发销毁逻辑:
private bool _markedForDestruction = false; void OnCollisionEnter(Collision col) { if (col.gameObject.CompareTag(gameObject.tag) && !_markedForDestruction) { TrafficCar otherCar = col.gameObject.GetComponent<TrafficCar>(); // 检查对方是否未被标记,避免双方同时触发销毁 if (!otherCar._markedForDestruction) { _markedForDestruction = true; Destroy(gameObject, 1f); // 对象池版本: // ObjectPool.Instance.RecycleVehicle(gameObject); } } } // 若使用对象池,回收时记得重置标记 public void ResetVehicle() { _markedForDestruction = false; // 补充其他重置逻辑(比如位置、速度等) }
方法三:通过碰撞接触点精准判断
利用碰撞接触点的法线方向,判断哪辆车是被撞的一方(比如接触点在车辆后方,说明是被追尾,当前车辆为被撞方):
void OnCollisionEnter(Collision col) { if (col.gameObject.CompareTag(gameObject.tag)) { // 获取第一个碰撞接触点的法线方向 Vector3 contactNormal = col.contacts[0].normal; // 将法线转换为当前车辆的局部坐标系 Vector3 localNormal = transform.InverseTransformDirection(contactNormal); // 如果接触点法线指向车辆后方(z轴负方向),判定为被撞方 if (localNormal.z < -0.5f) { Destroy(gameObject, 1f); // 对象池版本: // ObjectPool.Instance.RecycleVehicle(gameObject); } } }
内容的提问来源于stack exchange,提问作者user17248503
相关产品推荐
相关产品推荐

