Search Unity

Navmesh Agent randomly stopping while moving.

Discussion in 'Scripting' started by Robster95, Nov 27, 2020.

  1. Robster95

    Robster95

    Joined:
    Jul 3, 2019
    Posts:
    154
    Hey everyone I'm having a problem with my navmesh object following the player and randomly stopping in the a small radius around the same spot (theres a random spot with nothing there and if the agent goes within a radius of that spot it stops instantly)

    I dont have any code that changes the agent to stop at the instace ( i do have a state machine that changes the agent to stop moving but that code isnt being called for when it gets to that spot)

    I have no idea whats going on or why the aggent keeps stopping and i've been trying to figure this out for awhile and cant seem to get it. I'll drop my code for the whole agent below.

    P.s. the agent follows the player in the follow player state and looking at it in the inspector, when the agent stops its still in the follow player state and not switching to any other states (which would then make the agent stop moving)

    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine.AI;
    5. using UnityEngine;
    6. using EZCameraShake;
    7.  
    8. public class GhostsBehaviours : MonoBehaviour
    9. {
    10.     private Animator anim;
    11.     private NavMeshAgent navmesh;
    12.     private GameObject player;
    13.     private AudioSource enemyAudio;
    14.     [SerializeField]
    15.     private List<AudioClip> audioClips;
    16.  
    17.     private float audioClipOffset;
    18.  
    19.     [SerializeField]
    20.     private Transform areaSpot;
    21.     [SerializeField]
    22.     private float areaSpotRadius;
    23.     [SerializeField]
    24.     private float areaSpotTimer;
    25.     [SerializeField]
    26.     private List<Transform> areaSpotsList;
    27.     [SerializeField]
    28.     private float patrolSpotTimer = 2;
    29.  
    30.     [SerializeField]
    31.     private Material material;
    32.  
    33.     [SerializeField]
    34.     private Camera playerCam;
    35.     [SerializeField]
    36.     private Transform creatureCamPos;
    37.     [SerializeField]
    38.     private Transform positionToLookAt;
    39.  
    40.     public enum EnemyState
    41.     {
    42.         Patrol, FollowPlayer, Awake
    43.     }
    44.  
    45.     [SerializeField]
    46.     private EnemyState _currentState;
    47.  
    48.     private void Start()
    49.     {
    50.         areaSpotTimer = Random.Range(5, 15);
    51.         anim = GetComponent<Animator>();
    52.         navmesh = GetComponent<NavMeshAgent>();
    53.         player = GameObject.Find("Player");
    54.         enemyAudio = GetComponent<AudioSource>();
    55.  
    56.         material.color = Color.white;
    57.     }
    58.  
    59.     public void Update()
    60.     {
    61.         switch (_currentState)
    62.         {
    63.             case EnemyState.Awake:
    64.                 AwakeState();
    65.                 break;
    66.  
    67.             case EnemyState.FollowPlayer:
    68.                 FollowPlayerState();
    69.                 break;
    70.  
    71.             case EnemyState.Patrol:
    72.                 PatrolState();
    73.                 break;
    74.         }
    75.     }
    76.  
    77.     private void AwakeState()
    78.     {
    79.         areaSpotTimer = Random.Range(7, 15);
    80.     }
    81.    
    82.     private void FollowPlayerState()
    83.     {
    84.         float currentVal = anim.GetFloat("EnemyMovement");
    85.        
    86.         if(player.GetComponent<PlayerMovement>().isControllable)
    87.         {
    88.             //if its within range of the area spot
    89.             if (Vector3.Distance(areaSpot.position, player.transform.position) < 130)
    90.             {
    91.                 if (currentVal < 2)
    92.                 {
    93.                     anim.SetFloat("EnemyMovement", currentVal + (Time.deltaTime * 3f));
    94.                 }
    95.  
    96.                 navmesh.speed = 15;
    97.  
    98.                 NavMeshPath path = new NavMeshPath();
    99.                 navmesh.CalculatePath(player.transform.position, path);
    100.  
    101.                 if (player.transform.position != navmesh.destination)
    102.                 {
    103.                     navmesh.SetPath(path);
    104.                 }
    105.  
    106.                 transform.SetParent(areaSpot);
    107.             }
    108.  
    109.             //if its not within range
    110.             else
    111.             {
    112.                 navmesh.speed = Mathf.Lerp(navmesh.speed, 4, Time.deltaTime * 1);
    113.  
    114.                 anim.SetFloat("EnemyMovement", currentVal - (Time.deltaTime));
    115.  
    116.                 patrolSpotTimer = 2;
    117.  
    118.  
    119.                 if (navmesh.speed <= 7)
    120.                 {
    121.                     navmesh.SetDestination(transform.position);
    122.  
    123.                     _currentState = EnemyState.Patrol;
    124.                 }
    125.             }
    126.  
    127.             if (Vector3.Distance(transform.position, player.transform.position) <= navmesh.stoppingDistance)
    128.             {
    129.                 player.GetComponent<PlayerMovement>().isControllable = false;
    130.  
    131.                 KillPlayer();
    132.             }
    133.         }
    134.  
    135.         else
    136.         {
    137.             navmesh.SetDestination(transform.position);
    138.  
    139.             _currentState = EnemyState.Patrol;
    140.         }
    141.     }
    142.  
    143.     private void PatrolState()
    144.     {
    145.         //find new patrol spot
    146.         if(patrolSpotTimer > 0)
    147.         {
    148.             patrolSpotTimer -= Time.deltaTime;
    149.  
    150.             if(patrolSpotTimer <= 0)
    151.             {
    152.                 PatrolToNewSpots();
    153.  
    154.                 patrolSpotTimer = Random.Range(7, 15);
    155.             }
    156.         }
    157.  
    158.  
    159.         float currentval = anim.GetFloat("EnemyMovement");
    160.  
    161.         if (navmesh.velocity.magnitude != 0)
    162.         {
    163.             if(currentval < 1)
    164.             {
    165.                 anim.SetFloat("EnemyMovement", currentval + (Time.deltaTime * 2f));
    166.             }
    167.         }
    168.  
    169.         else
    170.         {
    171.             if(currentval > 0)
    172.             {
    173.                 anim.SetFloat("EnemyMovement", currentval - (Time.deltaTime * 2f));
    174.             }
    175.         }
    176.  
    177.         //if the player is inside the boundaries
    178.         if (Vector3.Distance(areaSpot.position, player.transform.position) < areaSpotRadius)
    179.         {
    180.             if (areaSpotTimer > 0)
    181.             {
    182.                 areaSpotTimer -= Time.deltaTime;
    183.             }
    184.  
    185.             else if (areaSpotTimer <= 0)
    186.             {
    187.                 ChangeMatColorWhenIrritated();
    188.             }
    189.         }
    190.  
    191.         //if the player is NOT inside the boundaries
    192.         else
    193.         {
    194.             ChangeMatColorWhenCalmingDown();
    195.         }
    196.  
    197.         GhostPatrolSounds();
    198.     }
    199.  
    200.     private void KillPlayer()
    201.     {
    202.         playerCam.gameObject.GetComponent<CameraShaker>().enabled = false;
    203.  
    204.         //moves the players camera onto the creature
    205.         playerCam.transform.parent = creatureCamPos;
    206.  
    207.         playerCam.transform.position = creatureCamPos.position;
    208.  
    209.  
    210.         anim.SetTrigger("KillPlayer");
    211.  
    212.         //enemyAudio.PlayOneShot(audioClips[1]);
    213.  
    214.         var pausemenu = GameObject.Find("Canvas").GetComponent<PauseMenu>();
    215.         pausemenu.TurnOffFlashLight();
    216.  
    217.         Invoke("BlackScreen", 1);
    218.         playerCam.transform.LookAt(positionToLookAt);
    219.     }
    220.  
    221.     void ChangeMatColorWhenIrritated()
    222.     {
    223.         Color targetColor = new Color(.5f, 0, 0, 1);
    224.  
    225.         if (material.color != targetColor)
    226.         {
    227.             material.color = Color.Lerp(material.color, targetColor, Time.deltaTime * 3);
    228.         }
    229.  
    230.         else
    231.         {
    232.             navmesh.SetDestination(transform.position);
    233.  
    234.             anim.SetTrigger("ChasePlayer");
    235.  
    236.             _currentState = EnemyState.Awake;
    237.         }
    238.     }
    239.  
    240.     void ChangeMatColorWhenCalmingDown()
    241.     {
    242.         Color currentColor = material.color;
    243.  
    244.         if (material.color != Color.white)
    245.         {
    246.             material.color = Color.Lerp(currentColor, Color.white, Time.deltaTime * 3);
    247.         }
    248.  
    249.         if(areaSpotTimer <= 0)
    250.         {
    251.             areaSpotTimer = Random.Range(5, 15);
    252.         }
    253.     }
    254.  
    255.     public void FollowPlayerBool()
    256.     {
    257.         _currentState = EnemyState.FollowPlayer;
    258.  
    259.         //navmesh.SetDestination(player.transform.position);
    260.     }
    261.  
    262.     private void PatrolToNewSpots()
    263.     {
    264.         navmesh.speed = 4f;
    265.  
    266.         for (int i = Random.Range(0, areaSpotsList.Count - 1); i < areaSpotsList.Count; i++)
    267.         {
    268.             if (areaSpotsList[i].childCount == 0)
    269.             {
    270.                 navmesh.SetDestination(areaSpotsList[i].position);
    271.  
    272.                 transform.SetParent(areaSpotsList[i]);
    273.                 return;
    274.             }
    275.         }
    276.     }
    277.  
    278.     private void BlackScreen()
    279.     {
    280.         var pausemenu = GameObject.Find("Canvas").GetComponent<PauseMenu>();
    281.  
    282.         pausemenu.BlackScreenEnabled();
    283.     }
    284.  
    285.  
    286.     private void GhostPatrolSounds()
    287.     {
    288.         if (audioClipOffset > 0)
    289.         {
    290.             audioClipOffset -= Time.deltaTime;
    291.         }
    292.  
    293.         else
    294.         {
    295.             for (int i = Random.Range(0, audioClips.Count - 1); i < audioClips.Count; i++)
    296.             {
    297.                 enemyAudio.pitch = Random.Range(.9f, 1.2f);
    298.                 enemyAudio.PlayOneShot(audioClips[i]);
    299.  
    300.                 audioClipOffset = Random.Range(1, 3) + audioClips[i].length;
    301.                
    302.                 return;
    303.             }
    304.         }
    305.     }
    306.  
    307.     private void GhostScreamClip(AudioClip clip)
    308.     {
    309.         enemyAudio.pitch = Random.Range(.5f, 1);
    310.         enemyAudio.PlayOneShot(clip, 2);
    311.  
    312.     }
    313.  
    314.     private void GhostSoundEffects(AudioClip clip)
    315.     {
    316.         enemyAudio.PlayOneShot(clip, 5f);
    317.     }
    318.  
    319.     private void OnDrawGizmos()
    320.     {
    321.         Gizmos.DrawWireSphere(areaSpot.position, areaSpotRadius);
    322.     }
    323. }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    Is that spot around (0,0,0)?

    What happens if you create a new blank level, put paths in it and try and run around?

    You have to isolate if it is code or the navmesh data itself.
     
  3. Robster95

    Robster95

    Joined:
    Jul 3, 2019
    Posts:
    154
    it's not at 0,0,0 its at a small part of the world (terrain) which is basically at (831,110, 320),

    and putting it into a new scene and testing it. it seems to be the navmesh. the other scene didnt have any problems with the agent following the player
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    If you zoom into the navmesh at that point, is there anything "unusual" there, like a lot of small pieces or a hole?

    Try putting a small flattish collider where the issue is and rebuilding navmesh, see if it bridges through.
     
  5. Robster95

    Robster95

    Joined:
    Jul 3, 2019
    Posts:
    154
    theres no difference in the navmesh. its a flat area that I tried to work on and change a little bit with the terrain building. theres no unusual spots on the navmesh. its a smooth and flat terrain
     
  6. Robster95

    Robster95

    Joined:
    Jul 3, 2019
    Posts:
    154
    thats a picture of the navmesh. I drew the blue dot where the navmesh has the problem but theres no inconsistencies in the navmesh
     

    Attached Files:

  7. adamsearle

    adamsearle

    Joined:
    Apr 16, 2021
    Posts:
    2
    Did you fix this issue? I'm having a similar issue where if I place an object with carve at runtime in the path of the agent sometimes they get stuck on nothing.
     
  8. Robster95

    Robster95

    Joined:
    Jul 3, 2019
    Posts:
    154
    I actually dont remember what I did to fix this issue. I remember it just was fixed one day. The best thing I can say is work on the agents avoidance and make sure the spot it's trying to go to is on a valid position on the navmesh. If it's not on the navmesh at all the agent wont try to go there since it wont have a valid path!
     
  9. SHARYPOWER

    SHARYPOWER

    Joined:
    Jan 19, 2022
    Posts:
    17
    I have the same issue with my TowerDefense game. On the right hand side the enemies are going normally while on the left one they are stuck just after they turning. I'am looking for the answers now...
     
  10. stanchoi2015

    stanchoi2015

    Joined:
    Jun 10, 2019
    Posts:
    1
    I have the same issue too. My zombie navmesh agents keeps stopping at some random points. If anybody who have any idea to solve this problem, please tell us ;(