Search Unity

Beginner question regarding AI view radius and line of sight

Discussion in 'Scripting' started by PaperMouseGames, Nov 14, 2019.

  1. PaperMouseGames

    PaperMouseGames

    Joined:
    Jul 31, 2018
    Posts:
    434
    Hi there! I'm working with AI for my 3D RPG and I'm having a small issue with my current setup.

    So the AI is a NavMeshAgent and I was making the AI wander to a random location on the NavMesh, but if the player gets within a certain radius, the AI began chasing the player.

    Here is that part of my AI code:

    Code (CSharp):
    1. private void Update()
    2.     {                
    3.         Follow();      
    4.         Wander();      
    5.     }
    6. private void Follow()
    7.     {
    8.         if (followPlayer)
    9.         {
    10.             distance = Vector3.Distance(transform.position, player.transform.position);            
    11.  
    12.             if (distance <= chaseRadius)
    13.             {
    14.                 agent.SetDestination(player.transform.position);
    15.             }
    16.             if (distance <= attackRadius)
    17.             {              
    18.                 RotateTowards(player.transform);
    19.                 Attack();
    20.             }
    21.             if (distance > chaseRadius)
    22.             {
    23.                 if (wander)
    24.                 {
    25.                     if (newPos != null)
    26.                     {
    27.                         agent.SetDestination(newPos);
    28.                     }
    29.                    
    30.                 }
    31.             }
    32.         }
    33.     }
    34. private void Wander()
    35.     {
    36.         if (wander)
    37.         {
    38.             if (Vector3.Distance(transform.position, newPos) <= agent.stoppingDistance * 1.2f)
    39.             {
    40.                 positionMarker.GetComponent<MeshRenderer>().material = green;
    41.                 timer += Time.deltaTime;
    42.  
    43.                 if (timer >= waitTimer)
    44.                 {
    45.                     Debug.Log("<color=green>Looking for new wander location...</color>");
    46.                     //newPos = RandomNavSphere(transform.position, wanderRadius, -1);
    47.  
    48.  
    49.                     while (Vector3.Distance(transform.position, newPos) <= agent.stoppingDistance * minDistanceMultiplier)
    50.                     {
    51.                         newPos = RandomNavSphere(transform.position, wanderRadius, -1);
    52.                     }
    53.  
    54.  
    55.  
    56.                     agent.SetDestination(newPos);
    57.                     positionMarker.GetComponent<MeshRenderer>().material = red;
    58.                     positionMarker.transform.position = newPos;
    59.                     Debug.DrawLine(transform.position, newPos, Color.red, waitTimer);
    60.  
    61.                     timer = 0;
    62.                 }              
    63.             }
    64.         }      
    65.     }
    This was working fine with exterior locations along large terrains, but now I'm testing it out inside of a "dungeon" which is basically a simple 3D maze, and I've run into an issue I'm trying to figure out:

    The
    chaseRadius 
    is a sphere, so if the player is in a hallway above or bellow the AI, the AI will start trying to follow the player, which is not what I want. Even worse, the AI can get stuck because it will start following the player, then move in a way that the player is no longer in the radius of that sphere so it will move to a wander location, then start chasing the player again, stuck in a loop.

    I think what I want is for a sort of line of sight logic for the AI. I hadn't really given this much thought before, but it makes more sense anyway. So, the AI would need to be facing the player, and have a clear line of sight to the player (i.e. no objects, walls, or floors in between) before it starts chasing.

    I'm sure this is doable, but I honestly don't know where to start. Any tips or resources would be greatly welcome!!! Thanks so much!
     
  2. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,748
    You can simply check if Physics.Raycast hit the opponent before engaging him. Or, if you have some sort of rooms in your dungeon and keep track of them, it may be better to limit in what rooms the enemy script follows in additional to view radius.
     
  3. PaperMouseGames

    PaperMouseGames

    Joined:
    Jul 31, 2018
    Posts:
    434
    Sounds easy enough. So I would still keep a
    chaseRadius
    like I have now, but if the player enters that chase radius I would perform a raycast from the enemy to the player and see if it hits any obstacles?

    I'll give it a try!