Unity 2D垂直太空射击游戏子弹碰撞失效问题求助
问题排查与解决方案
核心问题出在碰撞检测代码的挂载对象错误:你把OnCollisionEnter2D写在了飞船的BulletFiring脚本里,只有飞船发生碰撞时才会触发这个方法,子弹碰撞目标时完全不会调用这段逻辑,所以既没有日志也不会销毁目标。
修复步骤
1. 给子弹预制体单独添加碰撞处理脚本
创建一个新的C#脚本(比如BulletBehaviour),把碰撞检测逻辑移到这个脚本里,然后挂载到子弹预制体上:
using UnityEngine; public class BulletBehaviour : MonoBehaviour { private void OnCollisionEnter2D(Collision2D collision) { // 忽略玩家和其他子弹 if (collision.gameObject.CompareTag("Player") || collision.gameObject.CompareTag("Bullet")) { return; } Debug.Log("Bullet collided with: " + collision.gameObject.name); // 销毁目标和当前子弹 Destroy(collision.gameObject); Destroy(gameObject); } }
2. 清理飞船的BulletFiring脚本
把原脚本里无效的rigidbody2D/collider2D注释和OnCollisionEnter2D方法删掉,保留发射逻辑即可:
using UnityEngine; using System.Collections; public class BulletFiring : MonoBehaviour { public GameObject bulletPrefab; public float bulletSpeed = 20f; public float bulletLifetime = 3f; void Update() { if (Input.GetKeyDown(KeyCode.Space)) { FireBullet(); } } void FireBullet() { GameObject bullet = Instantiate(bulletPrefab, transform.position, Quaternion.identity); Rigidbody2D bulletRigidbody = bullet.GetComponent<Rigidbody2D>(); bulletRigidbody.velocity = transform.up * bulletSpeed; StartCoroutine(DespawnBulletAfterDelay(bullet, bulletLifetime)); } IEnumerator DespawnBulletAfterDelay(GameObject bullet, float delay) { yield return new WaitForSeconds(delay); Destroy(bullet); } }
3. 检查碰撞组件的关键设置
- Rigidbody2D设置:子弹或目标的Rigidbody2D至少有一个的
Body Type设为Dynamic(静态刚体不会触发碰撞事件); - CircleCollider2D设置:确保
Is Trigger未勾选(如果勾选了,要把OnCollisionEnter2D改成OnTriggerEnter2D); - Physics2D碰撞矩阵:打开
Edit > Project Settings > Physics2D,确认子弹所在的层和目标所在的层允许互相碰撞; - 标签检查:目标对象的标签不要是
Player或Bullet,确保碰撞时能进入销毁逻辑。
4. 验证效果
运行游戏后,子弹碰撞目标时应该会输出对应日志,并且目标和子弹都会被销毁。
内容的提问来源于stack exchange,提问作者Fei
相关产品推荐
相关产品推荐

