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

Unity 3D:为敌人AI实现带周边视野的射线检测可见性测试

实现Unity中敌人AI的扇形周边视野检测方案

要实现敌人的扇形周边视野,需要结合角度范围判断、距离范围验证和障碍物穿透检测,同时兼顾检测效率,以下是具体实现方案:

1. 核心逻辑梳理

敌人判定玩家在视野内,需同时满足三个条件:

  • 玩家处于设定的视野距离范围内
  • 玩家处于敌人的扇形视野角度范围内
  • 敌人与玩家之间无障碍物阻挡

2. 角度与距离范围判断

通过向量计算快速筛选出可能在视野内的玩家:

  • 利用敌人Transform的forward属性获取正前方方向
  • 计算敌人到玩家的方向向量并归一化,通过Vector3.Angle计算夹角,判断是否在视野角度的半值范围内(例如视野总角度90°,则夹角需≤45°)
  • 同步验证敌人与玩家的直线距离是否≤设定的视野距离

示例代码片段:

public class EnemyAI : MonoBehaviour
{
    public float viewDistance = 12f;
    public float viewAngle = 90f; // 扇形视野的总覆盖角度
    public LayerMask playerLayer;
    public LayerMask obstacleLayer;
    private Transform playerTrans;

    void Start()
    {
        playerTrans = GameObject.FindGameObjectWithTag("Player").transform;
    }

    void Update()
    {
        DetectPlayerInView();
    }

    void DetectPlayerInView()
    {
        Vector3 dirToPlayer = playerTrans.position - transform.position;
        float distance = dirToPlayer.magnitude;

        // 1. 距离超出视野范围,直接返回
        if (distance > viewDistance) return;

        // 2. 不在扇形角度范围内,直接返回
        dirToPlayer.Normalize();
        float angle = Vector3.Angle(transform.forward, dirToPlayer);
        if (angle > viewAngle / 2f) return;

        // 3. 无障碍物阻挡,触发追击逻辑
        if (!HasObstacleBlocking(dirToPlayer, distance))
        {
            ChasePlayer();
        }
    }
}

3. 障碍物穿透检测优化

单射线检测可能存在漏检(例如玩家处于扇形边缘时射线未命中),可采用以下两种方案:

方案一:多射线覆盖扇形区域

在视野扇形内均匀发射多条射线,确保覆盖整个视野范围:

bool HasObstacleBlocking(Vector3 dirToPlayer, float distance)
{
    // 发射中心射线
    if (Physics.Raycast(transform.position, dirToPlayer, distance, obstacleLayer))
        return true;

    // 发射左右偏移射线,数量可根据视野角度调整
    int rayCount = 3;
    float angleStep = viewAngle / (rayCount - 1);
    for (int i = 0; i < rayCount; i++)
    {
        float offsetAngle = -viewAngle / 2f + angleStep * i;
        Vector3 rayDir = Quaternion.Euler(0, offsetAngle, 0) * transform.forward;
        if (Physics.Raycast(transform.position, rayDir, distance, obstacleLayer))
            return true;
    }
    return false;
}

方案二:球体投射(SphereCast)

相比单射线,球体投射可检测更宽的区域,避免小障碍物误判,适合覆盖扇形视野:

bool HasObstacleBlocking(Vector3 dirToPlayer, float distance)
{
    float sphereRadius = 0.4f; // 根据敌人、玩家模型大小调整
    if (Physics.SphereCast(transform.position, sphereRadius, dirToPlayer, out RaycastHit hit, distance, obstacleLayer))
    {
        // 若命中对象是玩家,则无阻挡;否则为障碍物
        return !hit.collider.CompareTag("Player");
    }
    return false;
}

4. 性能优化建议

  • 先用Physics.OverlapSphere筛选出视野范围内的玩家对象,再对这些对象执行角度和障碍物检测,减少无效计算:
Collider[] inRangePlayers = Physics.OverlapSphere(transform.position, viewDistance, playerLayer);
foreach (Collider col in inRangePlayers)
{
    Transform target = col.transform;
    // 对每个目标执行角度与障碍物检测逻辑
}
  • 给玩家、障碍物设置独立分层,通过LayerMask精准过滤检测对象,避免检测无关物体。

内容的提问来源于stack exchange,提问作者yassin eltaramsi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 06:36:49