Unity开发:如何删除爆炸半径范围内的游戏对象
问题原因分析
- 核心逻辑反向错误:当前代码
if(!explosion)表示只有对象上不存在Explosion组件时才进入销毁逻辑,此时explosion变量为空,执行Destroy(explosion.gameObject)会直接抛出空引用异常,逻辑完全无法执行。 - 冗余判断:
Physics.OverlapSphere接口返回的碰撞体本身就处于你设定的爆炸半径范围内,不需要额外再调用Vector3.Distance重复判断距离。 - 销毁目标不明确:如果你的需求是销毁爆炸范围内所有带刚体的单位,不需要额外判断
Explosion组件;如果是仅销毁范围内的爆炸物,应该在找到Explosion组件时执行销毁。
修正方案
根据常见的两种开发需求,对应修正代码如下:
场景1:销毁爆炸范围内所有带刚体的对象
public void Explode() { Collider[] overlappedColliders = Physics.OverlapSphere(transform.position, Radius); for(int i = 0; i < overlappedColliders.Length; i++) { Rigidbody rigidbody = overlappedColliders[i].attachedRigidbody; if(rigidbody) { rigidbody.AddExplosionForce(Force, transform.position, Radius, 1f); // 直接销毁刚体对应的游戏对象 Destroy(rigidbody.gameObject); } } }
场景2:仅销毁爆炸范围内带Explosion组件的爆炸物对象
public void Explode() { Collider[] overlappedColliders = Physics.OverlapSphere(transform.position, Radius); for(int i = 0; i < overlappedColliders.Length; i++) { Rigidbody rigidbody = overlappedColliders[i].attachedRigidbody; if(rigidbody) { rigidbody.AddExplosionForce(Force, transform.position, Radius, 1f); Explosion explosion = rigidbody.GetComponent<Explosion>(); // 找到Explosion组件时执行销毁 if(explosion != null) { Destroy(explosion.gameObject); } } } }
额外优化建议
你当前的OnCollisionEnter执行顺序存在隐患,应该先生成爆炸特效、执行爆炸逻辑,最后销毁自身,避免销毁自身后逻辑执行异常,修正后代码如下:
public void OnCollisionEnter (Collision collision) { if(collision.gameObject.tag == "Explosion") { Instantiate(ExplosionEffect, transform.position, Quaternion.identity); Explode(); Destroy(gameObject); } }
内容的提问来源于stack exchange,提问作者Дмитрий Тиханский
相关产品推荐
相关产品推荐

