Search Unity

Wanderer moving too fast?

Discussion in 'Navigation' started by tacosontitan, Jul 15, 2021.

  1. tacosontitan

    tacosontitan

    Joined:
    Feb 16, 2021
    Posts:
    8
    I've successfully created a wander script using a NavMeshAgent, but it's moving too fast and I can't figure out how to slow it down. It may just be that I don't fully understand how the NavMeshAgent works yet, but it's driving me nuts since I've tinkered with the speed and acceleration to the low end values of 0.0005 and that resulted in almost no movement. The following video makes it look like the agent isn't moving, but it is (just really slowly).When I select the capsule that I've added the NavMeshAgent to in the inspector it just takes off, which to me is even weirder behavior.



    With all of the above out of the way, my wander script is pretty straight forward:

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. using UnityEngine.AI;
    4.  
    5. [RequireComponent(typeof(NavMeshAgent))]
    6. public class Wander : MonoBehaviour {
    7.  
    8.     #region Fields
    9.  
    10.     private NavMeshAgent _navMeshAgent;
    11.  
    12.     #endregion
    13.  
    14.     #region Properties
    15.  
    16.     [field: SerializeField] public int NavigationSamplerLayer { get; set; } = 0;
    17.     [field: SerializeField] public float DelayBetweenRoutes { get; set; } = 3;
    18.     [field: SerializeField] public float MaximumRouteDistance { get; set; } = 10;
    19.  
    20.     #endregion
    21.  
    22.     void Awake() {
    23.         if (!TryGetComponent(out _navMeshAgent))
    24.         {
    25.             Debug.LogError($"Wanderer `{name}` unable to locate a NavMeshAgent on wake.");
    26.             return;
    27.         }
    28.  
    29.         StartCoroutine(UpdateWander());
    30.     }
    31.     IEnumerator UpdateWander() {
    32.         while (true) {
    33.             _navMeshAgent.SetDestination(GetNewWaypoint());
    34.             while (_navMeshAgent.velocity.magnitude > 0.5f)
    35.                 yield return new WaitForSeconds(1);
    36.  
    37.             yield return new WaitForSeconds(DelayBetweenRoutes);
    38.         }
    39.     }
    40.     public Vector3 GetNewWaypoint() {
    41.         NavMesh.SamplePosition(transform.position + Random.insideUnitSphere * MaximumRouteDistance, out NavMeshHit navHit, MaximumRouteDistance, NavigationSamplerLayer);
    42.         return navHit.position;
    43.     }
    44. }
    How can I slow it down?
     
  2. tacosontitan

    tacosontitan

    Joined:
    Feb 16, 2021
    Posts:
    8
    One problem I found so far is in the fact UpdateWander was continuously setting a new waypoint. Adding a boolean to determine if a new path is needed helps:

    Code (CSharp):
    1. IEnumerator UpdateWander() {
    2.     while (true) {
    3.         if (_newPathNeeded) {
    4.             _navMeshAgent.SetDestination(GetNewWaypoint());
    5.             _newPathNeeded = false;
    6.         }
    7.  
    8.         while (_navMeshAgent.velocity.magnitude > 0.5f)
    9.             yield return new WaitForSeconds(1);
    10.  
    11.         _newPathNeeded = true;
    12.         yield return new WaitForSeconds(DelayBetweenRoutes);
    13.     }
    14. }
    But it's still having issues. Still debugging and reviewing, will post any new information as I find it.
     
  3. tacosontitan

    tacosontitan

    Joined:
    Feb 16, 2021
    Posts:
    8
    After some more adjustments, it turns out the issue was contained to the UpdateWander method. After adjusting it, the object will wander to a location, wait a moment, then wander to a new location.

    Code (CSharp):
    1. IEnumerator UpdateWander() {
    2.     while (true) {
    3.         if (!_firstRun)
    4.             yield return new WaitForSeconds(DelayBetweenRoutes);
    5.         else
    6.             _firstRun = false;
    7.  
    8.         if (!_navMeshAgent.hasPath) {
    9.             _navMeshAgent.SetDestination(GetNewWaypoint());
    10.             yield return new WaitUntil(() => _navMeshAgent.hasPath);
    11.         }
    12.         else
    13.             yield return new WaitUntil(() => !_navMeshAgent.hasPath);
    14.     }
    15. }