Home > Enterprise >  Unity-3D, Enemy using Raycast and NavMesh keeps seeing me through walls
Unity-3D, Enemy using Raycast and NavMesh keeps seeing me through walls

Time:12-15

I've been trying to set an enemy on a patrol path while not chasing my player character. I want to use RayCast so that the enemy can spot the player and begin to chase the player. It functions as I intended. However, even when there's an obstacle or wall between us, or when I approach from behind, the enemy 'sees' my player and starts to chase me. It seems to ignore the Raycast, and instead focuses on the proximity to the enemy.

Enemy spotting player through wall

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();
        }
    }
}

I've removed the tilde "~" for the layermask, but then the enemy doesn't ever see the player. I've initialised and set a layer mask reference to the 'playerLayer' and used it in place of "layermask: ~6", to no avail. I've used the int reference to the Player layer, to no avail. I've used bitwise operator to reference the player layer, to no avail. I've removed the distanceToPlayer conditional, but the enemy doesn't see the player. I've adjusted the length of the Ray but if it's ever shorter than the attack radius, it doesn't work.

CodePudding user response:

regarding player detection through a wall,I would try adding an extra if statement in the Lurk method.This condition would check if the raycast is touching the wall, if so, do not proceed with the method, if not, continue. Sorry for giving the code in this form but I don't have access to a computer and the phone doesn't want to cooperate

enter image description here

CodePudding user response:

I don't understand why you need a layer mask. If you want the Raycast to hit something in front of the player then you must include all layers in the Raycast.

What you need to do is remove the layermask from Raycast and in the if statement check if the out hit collider is on Player and if the player is in attack radius. Here is a simple outline

If(raycast)
{
  if(hit.collider.gameobject==player && player in proximity)
  {
    Then can see is true
  }
}

You can give this article on Unity Raycast a read to understand more on layermask.

  • Related