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

Unity 3D自定义射线检测形状:舰船火炮扇区瞄准问题求解

舰船火炮扇区目标分配问题

我制作了一艘可射击目标的舰船,要求右侧火炮不得瞄准舰船左侧的目标。使用Vector3.SignedAngle函数划分扇区后,测试基本可用但存在明显缺陷:

  • 当前扇区为单点锥形(图1),无法检测舰船侧前方的近距离目标;
  • 增大角度阈值后(图2),虽能覆盖更多目标,但会出现红色标记的错误扇区;
  • 理想扇区应为底部较宽的锥形(图3),解决单点判断带来的问题。
    尝试过BoxCast方法,但不适用当前场景。

现有目标分配脚本

foreach (Transform target in EnemyListManager.instance.enemyShips.ToArray())
{
    if (Vector3.Distance(transform.position, target.position) > ship.mainGunCaliber.range)
        continue;

    Vector3 toTarget = target.position - transform.position;
    print(Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up));

    if (Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up) >= bowMinAngle &&
        Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up) <= bowMaxAngle)
    {
        if (!bowTargets.Contains(target))
        {
            RemoveFromOthers(target);
            bowTargets.Add(target);
            print("added target to Bow");
        }
        continue;
    }
    if (Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up) >= sbMinAngle &&
        Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up) <= sbMaxAngle)
    {
        if (!sbTargets.Contains(target))
        {
            RemoveFromOthers(target);
            sbTargets.Add(target);
            print("added target to SB");
        }
        continue;
    }
    if (Vector3.SignedAngle(-hullParent.forward, toTarget, Vector3.up) >= aftMinAngle &&
        Vector3.SignedAngle(-hullParent.forward, toTarget, Vector3.up) <= aftMaxAngle)
    {
        if (!aftTargets.Contains(target))
        {
            RemoveFromOthers(target);
            aftTargets.Add(target);
            print("added target to Aft");
        }
        continue;
    }
    if (Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up) >= psMinAngle &&
        Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up) <= psMaxAngle)
    {
        if (!psTargets.Contains(target))
        {
            RemoveFromOthers(target);
            psTargets.Add(target);
            print("added target to PS");
        }
    }
}

解决方案

1. 基于舰船边界点的扇区判断

放弃单一中心角度判断,改用舰船侧舷的边界点来构建底部宽的锥形区域:

  • 预先计算舰船左右侧舷的关键参考点(比如船首左侧边缘、船首右侧边缘、船尾对应点),可在Start()方法中初始化;
  • 对目标同时计算从舰船中心、侧舷边界点到目标的角度,结合目标相对于船身的横向位置,判断是否属于对应火炮的允许区域。

示例代码片段:

// 初始化舰船边界点(需根据船身尺寸调整参数)
Vector3 portBowPoint = hullParent.TransformPoint(new Vector3(-shipWidth / 2, 0, shipLength / 2));
Vector3 starboardBowPoint = hullParent.TransformPoint(new Vector3(shipWidth / 2, 0, shipLength / 2));

// 目标判断逻辑(以右舷火炮为例)
Vector3 toTargetFromCenter = target.position - transform.position;
float centerAngle = Vector3.SignedAngle(hullParent.forward, toTargetFromCenter, Vector3.up);
// 获取目标在船身局部坐标系的X轴位置,判断是否在右舷允许范围内
float localTargetX = hullParent.InverseTransformPoint(target.position).x;

// 右舷火炮允许条件:中心角度在右舷扇区范围内,且目标未完全处于船身左侧
bool isStarboardValid = centerAngle >= sbMinAngle && centerAngle <= sbMaxAngle && localTargetX >= -shipWidth / 4;

if (isStarboardValid && !sbTargets.Contains(target))
{
    RemoveFromOthers(target);
    sbTargets.Add(target);
    print("added target to SB");
}

2. 多边形碰撞区域检测

将每个火炮的允许射击区域定义为多边形碰撞体,直接判断目标是否在区域内:

  • 创建空物体作为扇区碰撞区域,添加PolygonCollider2D(2D场景)或MeshCollider(3D场景),手动调整顶点形成底部宽的锥形;
  • 将碰撞区域设为触发器,避免参与物理碰撞;
  • 对每个目标,使用PolygonCollider2D.OverlapPoint(2D)或Physics.OverlapPoint(3D)判断是否在对应扇区内。

3. 动态角度阈值调整

根据目标距离动态调整角度范围,适配不同距离的目标:

  • 近距离目标时,放宽角度阈值(船身宽度占比大,近距离左侧目标不会被右舷火炮命中);
  • 远距离目标时,收窄角度阈值,保持原有的单点角度判断逻辑。

示例代码片段:

float distance = Vector3.Distance(transform.position, target.position);
// 动态偏移量:近距离最大30度,远距离降为0度
float dynamicOffset = Mathf.Lerp(30f, 0f, distance / ship.mainGunCaliber.range);

float signedAngle = Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up);
// 右舷扇区范围:原阈值±动态偏移,同时限制目标横向位置
bool isStarboardValid = signedAngle >= sbMinAngle - dynamicOffset && 
                       signedAngle <= sbMaxAngle + dynamicOffset &&
                       hullParent.InverseTransformPoint(target.position).x >= -shipWidth / 4;

内容的提问来源于stack exchange,提问作者Mad Hatter

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 06:45:39