Search Unity

NavMesh Agent Jumps To Destination

Discussion in 'Navigation' started by JoelLB, Oct 15, 2019.

  1. JoelLB

    JoelLB

    Joined:
    Oct 9, 2019
    Posts:
    25
    Hi All,
    I need some help.
    I have a navmesh agent that wants to jump to some destinations rather than animate to it.
    Each destination is created randomly and then assigned to the agent's destination.

    What might cause the jumping?



    Code (CSharp):
    1.  
    2.     void Update()
    3.     {
    4.         NavMeshAgent agent = GetComponent<NavMeshAgent>();
    5.  
    6.         if ((agent.transform.position.x > agent.destination.x - 1 && agent.transform.position.x < agent.destination.x + 1) &&
    7.             (agent.transform.position.z > agent.destination.z - 1 && agent.transform.position.z < agent.destination.z + 1) && isMoving)
    8.  
    9.         {
    10.             Destroy(Waypoint);
    11.             isMoving = false;
    12.             Debug.Log("ReachedDest");
    13.             moveCharacter = false;
    14.             timer = 0;
    15.             needToAnimate = true;
    16.             newAnimationID = 0;
    17.         }
    18.  
    19.         if (secondsSinceLastMoved > secondsNeededTillMove && isMoving == false)
    20.         {
    21.             moveCharacter = true;
    22.             secondsSinceLastMoved = 0;
    23.             currentPosition = this.transform;
    24.             float newX = Random.Range(-18.44f, 33.89f);
    25.             float newY = Random.Range(0f, 0f);
    26.             float newZ = Random.Range(-5.5f, 13.47f);
    27.             if (currentPosition.position.z + newZ > 5.92f)
    28.             {
    29.                 newZ = 5.92f;
    30.             }
    31.             if (currentPosition.position.z + newZ < -0.94f)
    32.             {
    33.                 newZ = -0.94f;
    34.             }
    35.             Debug.Log("currentPosition.position.x" + currentPosition.position.x);
    36.             newPosition = currentPosition;
    37.             newPosition.transform.position = new Vector3(newX, newY, newZ);
    38.             Waypoint = new GameObject();
    39.             Waypoint.name = "DestWaypoint";
    40.             Waypoint.transform.position = newPosition.position;
    41.  
    42.             //Instantiate(Waypoint, this.transform);
    43.             timer = 0f;
    44.             isMoving = true;
    45.             needToAnimate = true;
    46.             newAnimationID = 1;
    47.             MoveCharacter(Waypoint);
    48.  
    49.         }
    50.  
    51.         if (needToAnimate)
    52.             crossfadeAnimation(newAnimationID);
    53.  
    54.         if (!moveCharacter)
    55.        
    56.         {
    57.             timer += Time.deltaTime;
    58.             secondsSinceLastMoved = Convert.ToInt32(timer % 60);
    59.         }
    60.  
    61.  
    62.  
    63.     }
    64.  
    65.  

    Code (CSharp):
    1.  
    2.   void MoveCharacter(GameObject WaypointGameObject)
    3.     {
    4.  
    5.         NavMeshAgent agent = GetComponent<NavMeshAgent>();
    6.         agent.destination = WaypointGameObject.transform.position;
    7.  
    8.         //If Character has reached new position
    9.  
    10.  
    11.     }
    12.  
     
    Last edited: Oct 15, 2019
  2. Yandalf

    Yandalf

    Joined:
    Feb 11, 2014
    Posts:
    491
    Because you're immediately setting the position of currentTransform, which you've first set to be this.transform.
    Effectively, you're just setting your position there with a ton of code in-between that does effectively nothing.
    If I were you I'd rewrite this to something much simpler like:
    Code (CSharp):
    1. void Update()
    2. {
    3. isMoving = navMeshAgent.velocity.sqrMagnitude > 0;
    4. if(!isMoving)
    5. {
    6. if(timeSinceMoved > timeToMove)
    7. {
    8. navMeshAgent.SetDestination(somePosition);
    9. timeSinceMoved = 0f;
    10. }
    11. else
    12. {
    13. timeSinceMoved += Time.deltaTime;
    14. }
    15. }
    16. }
    There are ways to wire an Animator and a NavMeshAgent together that don't require a ton of error-prone code, you should read up on that here. Maybe also just take a look at the standard 3rd Person Controller. It probably already does a lot of what you're trying to do.

    Also, for the love of God, don't use GetComponent every Update. It's an incredibly expensive operation to do so often.
    It's much better to use it once at Start to store your components in a variable:

    Code (CSharp):
    1. private NavMeshAgent _navmeshAgent;
    2.  
    3. void Start()
    4. {
    5. _navmeshAgent = GetComponent<NavmeshAgent>();
    6. }
    7.  
    8. //everywhere else just use _navmeshAgent
     
  3. cmyd

    cmyd

    Joined:
    Oct 29, 2017
    Posts:
    98
    I'm gonna go slightly off topic mate, Your code isn't optimized at all, in fact its breaking the concept of re usability, You need to work on that.
    Let me give you an example.

    you don't need to use
    Code (CSharp):
    1.  
    2. NavMeshAgent agent = GetComponent<NavMeshAgent>();
    3.  
    in update, what you can do is in your start() method
    Code (CSharp):
    1.  
    2.  
    3. NavMeshAgent agent;
    4. void Start(){
    5.     agent = GetComponent<NavMeshAgent>();
    6. }
    7.  
    Now use agent in your script.