Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

My NPC is not switching from running away state to random movement state.

Discussion in 'Navigation' started by Coyroski, Nov 20, 2021.

  1. Coyroski

    Coyroski

    Joined:
    May 19, 2020
    Posts:
    8
    Heres the code I wrote. I'm using NavMeshAgent for the navigation. The NPC does random movement with the RandomMovement() function. When the player gets behind the NPC and is detected by the spherecast, the seenplayer bool gets set to true and the Runaway() function should run. The issue I'm having is that when the player is chasing the NPC and the player stops, the NPC should continue running away up to the runawayRadius distance which is further away that the spherecast rearViewDectionRange. The Runaway() also calls a couroutine to refresh the position to runaway to every set amount of time instead of every tick of fixed update, since having lots of the NPCs on screen slows down my machine.

    But the NPC just runs away to a up to a random distance and just stays there, it doesn't switch back to the RandomMovement() function. Unless I walk backwards away from the NPC it somehow starts the RandomMovement() function again.

    Code (CSharp):
    1. void FixedUpdate()
    2.     {
    3.         NavMeshAgent agent = GetComponent<NavMeshAgent>();
    4.         RaycastHit rHit;
    5.  
    6.         if (!seenPlayer)
    7.         {
    8.             RandomMovement();
    9.  
    10.             if (Physics.SphereCast(eyes.transform.position, sphereCastThickness, -transform.forward, out rHit, rearViewDetectionRange)) //if (Physics.Raycast(viewRay, out rHit, viewDetectionRange))
    11.             {
    12.                 if (rHit.collider.tag == "Player")
    13.                 {
    14.                     seenPlayer = true;
    15.                 }
    16.             }
    17.             else
    18.                 seenPlayer = false;
    19.         }
    20.  
    21.         if (seenPlayer)
    22.         {
    23.             Runaway();
    24.         }
    25.     }
    26.  
    27.     void RandomMovement()
    28.     {
    29.         seenPlayer = false;
    30.         runningAway = false;
    31.    
    32.         distance = Vector3.Distance(player.position, transform.position);
    33.         Vector3 randomDirection = Random.insideUnitSphere * walkRadius;
    34.         randomDirection += transform.position;
    35.         NavMeshHit hit;
    36.         NavMesh.SamplePosition(randomDirection, out hit, walkRadius, 1);
    37.         Vector3 finalPosition = hit.position;
    38.         NavMeshAgent agent = GetComponent<NavMeshAgent>();
    39.         if (!agent.pathPending)
    40.         {
    41.             if (agent.remainingDistance <= agent.stoppingDistance)
    42.             {
    43.                 if (agent.hasPath || agent.velocity.sqrMagnitude == 0f)
    44.                 {
    45.                     if (timerStart == false)
    46.                     {
    47.                         agent.speed = walkSpeed;
    48.                         Debug.Log("Destination arrived.");
    49.                         idleTime = Random.Range(0, 11);
    50.                         timerStart = true;
    51.                         agent.autoBraking = true;
    52.                     }
    53.  
    54.                     if (timerStart == true)
    55.                     {
    56.                         idleTime -= Time.deltaTime;
    57.                     }
    58.                     if (idleTime <= 0f)
    59.                     {
    60.                         timerStart = false;
    61.                         Debug.Log("Agent Idle complete.");
    62.                         agent.CalculatePath(finalPosition, path);
    63.                         agent.SetPath(path);
    64.                     }
    65.                 }
    66.             }
    67.         }
    68.     }
    69.        
    70.  
    71.     void Runaway()
    72.     {
    73.         if (seenPlayer)
    74.         {
    75.             runningAway = true;
    76.             if (runningAway)
    77.             {
    78.                 NavMeshAgent agent = GetComponent<NavMeshAgent>();
    79.                 distance = Vector3.Distance(player.position, transform.position);
    80.                 if (runawayRadius > distance)
    81.                 {
    82.                     timerStart = false;
    83.                     //agent.SetDestination(newPos);
    84.                     //agent.SetDestination(newPos);
    85.                     StartCoroutine(PathCalls());
    86.                 }
    87.                 if (runawayRadius <= distance)
    88.                 {
    89.                     runningAway = false;
    90.                     agent.speed = walkSpeed;
    91.                     RandomMovement();
    92.                 }
    93.             }
    94.         }
    95.     }
    96.  
    97.     private IEnumerator PathCalls()
    98.     {
    99.         NavMeshAgent agent = GetComponent<NavMeshAgent>();
    100.         agent.speed = runAwaySpeed;
    101.         dirToPlayer = transform.position - player.transform.position;
    102.         newPos = transform.position + dirToPlayer;
    103.         agent.CalculatePath(newPos, path);
    104.         agent.SetPath(path);
    105.         agent.autoBraking = false;
    106.         yield return new WaitForSeconds(timeBetweenPathCalls);
    107.     }
     
    Last edited: Nov 20, 2021
  2. Coyroski

    Coyroski

    Joined:
    May 19, 2020
    Posts:
    8
    Okay it seems to be a problem with IEnumerator PathCalls(). I have a debug log there that shows that its being called but the code there isn't executing.