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

Unity3D敌人用Raycast和NavMesh穿墙识别玩家问题求助

敌人AI巡逻与追击功能故障排查

我正在实现一个敌人AI,逻辑设定为:未发现玩家时沿预设路径巡逻,通过Raycast检测到玩家后切换至追击状态。目前基础功能可用,但存在严重问题:即使玩家与敌人之间有障碍物/墙体阻隔,或是从敌人后方接近,敌人仍会触发追击逻辑,Raycast的视线判断似乎完全失效,仅依据距离条件启动追击。

敌人穿墙识别玩家

public class EnemyController : MonoBehaviour
{
    private NavMeshAgent enemy;// assaign navmesh agent
    private Transform playerTarget;// reference to player's position
    private float attackRadius = 10.0f; // radius where enemy will spot player
    public Transform[] destinationPoints;// array of points for enemy to patrol
    private int currentDestination;// reference to current position
    public bool canSeePlayer = false;
    private Ray enemyEyes;
    public RaycastHit hitData;


    private void Awake()
    {
        enemy = GetComponent<NavMeshAgent>();
        playerTarget = GameObject.Find("Player").GetComponent<Transform>();
        enemyEyes = new Ray(transform.position, transform.forward);
    }
    private void Start()
    {
        Physics.Raycast(enemyEyes, attackRadius);
    }
    private void Update()
    {
        Lurk();
        Debug.DrawRay(transform.position, transform.forward * attackRadius);
    }

    void Lurk()
    {
        Debug.Log("Lurking");
        float distanceToPlayer = Vector3.Distance(transform.position, playerTarget.position);
        //check if raycast hits playerLayer and enemy is close enough to attack
        if (Physics.Raycast(enemyEyes, out hitData, attackRadius * 2, layerMask: ~6) && distanceToPlayer < attackRadius)
        {
            Debug.Log("You hit " + hitData.collider.gameObject.name);
            ChasePlayer();
        }
        else
        {
            canSeePlayer = false;
            Patrol();
        }
    }
    void Patrol()
    {
        if (!canSeePlayer && enemy.remainingDistance < 0.5f)
        {
            enemy.destination = destinationPoints[currentDestination].position;
            UpdateCurrentPoint();
        }
    }

    void UpdateCurrentPoint()
    {
        if (currentDestination == destinationPoints.Length - 1)
        {
            currentDestination = 0;
        }
        else
        {
            currentDestination++;
        }
    }

    void ChasePlayer()
    {
        StartCoroutine(ChaseTime());
        canSeePlayer = true;
        transform.LookAt(playerTarget.position);
        Vector3 moveTo = Vector3.MoveTowards(transform.position, playerTarget.position, attackRadius);
        enemy.SetDestination(moveTo);
        
    }


    IEnumerator ChaseTime()
    {
        Debug.Log("Chasing");
        yield return new WaitForSeconds(10.0f);
        if (!Physics.Raycast(enemyEyes, out hitData, attackRadius * 2, layerMask: ~6))
        {
            canSeePlayer = false;
            Debug.Log("Lurking");
            Lurk();
        }
    }
}

已尝试的调试方案:

  • 移除LayerMask的波浪号“~”,敌人完全无法识别玩家
  • 初始化并使用playerLayer的LayerMask引用替换layerMask: ~6,无效果
  • 使用Player层的整数引用、位运算符引用,均无法解决问题
  • 移除distanceToPlayer条件后,敌人无法看到玩家
  • 调整射线长度,只要长度短于attackRadius就无法正常触发玩家识别

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 18:20:31