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
相关产品推荐
相关产品推荐

