You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 02:01:35