Unity高速穿透子弹射线检测无伤害问题排查求助
高速穿透子弹检测问题修复方案
核心问题分析
你的代码存在以下关键问题,导致射线无法命中预制体敌人:
1. 射线方向错误(2D环境致命问题)
2D游戏中transform.forward指向Z轴,而子弹沿XY平面移动,射线方向完全偏离目标,自然检测不到敌人。应使用子弹的移动方向(rb.velocity归一化向量)作为射线方向。
2. 射线检测逻辑漏洞
高速子弹可能在两帧之间直接穿过敌人,当前仅从子弹当前位置发射射线,无法覆盖移动轨迹。需改为检测上一帧位置到当前帧位置的完整路径。
3. 重复检测判断冗余
HitName初始化后永远不为null,HitName == null判断多余;且List的Contains效率低,建议改用HashSet<int>优化查找。
4. 组件获取无容错
直接调用GetComponent<EnemyMovement>()若敌人无该组件会触发空引用,中断后续逻辑。
5. LayerMask有效性未确认
需确保敌人预制体的Layer被包含在Enemies LayerMask中,否则射线会直接忽略敌人。
修复后的完整代码
using System.Collections.Generic; using UnityEngine; public class Bullet : MonoBehaviour { [Header("References")] [SerializeField] private Rigidbody2D rb; [Header("Attributes")] [SerializeField] private float bulletSpeed = 10f; [SerializeField] private LayerMask enemiesLayer; public Transform target; public Transform startPoint; public int damage; public float maxDistance; public int maxPierce; private int piercedCount; private HashSet<int> hitEnemyIDs = new HashSet<int>(); private Vector2 lastPosition; private void Start() { Vector2 direction = (target.position - transform.position).normalized; rb.velocity = direction * bulletSpeed; lastPosition = transform.position; } private void Update() { if (Vector2.Distance(startPoint.position, transform.position) >= maxDistance) { Destroy(gameObject); } } private void FixedUpdate() { Vector2 currentPosition = transform.position; Vector2 moveDirection = (currentPosition - lastPosition).normalized; float moveDistance = Vector2.Distance(lastPosition, currentPosition); // 覆盖子弹移动轨迹的射线检测 RaycastHit2D[] hits = Physics2D.RaycastAll(lastPosition, moveDirection, moveDistance, enemiesLayer); foreach (RaycastHit2D hit in hits) { if (piercedCount >= maxPierce) { Destroy(gameObject); return; } EnemyMovement enemy = hit.collider.GetComponent<EnemyMovement>(); if (enemy == null) continue; int enemyID = enemy.GetInstanceID(); if (!hitEnemyIDs.Contains(enemyID)) { hitEnemyIDs.Add(enemyID); enemy.Damage(damage); piercedCount++; } } lastPosition = currentPosition; } }
额外注意事项
- 敌人预制体必须带有
EnemyMovement组件,且Damage方法能正确处理伤害值。 - 敌人的Collider2D需处于启用状态,若使用Trigger需确保射线检测包含Trigger(可通过
Physics2D.RaycastAll的重载参数设置)。 - 子弹的Rigidbody2D需设为
Dynamic,Gravity Scale设为0,避免重力干扰移动方向。
内容的提问来源于stack exchange,提问作者kraken
相关产品推荐
相关产品推荐

