Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How To Know If NavMeshAgent Is Moving

Discussion in 'Scripting' started by renman3000, Dec 1, 2014.

  1. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,680
    Hi there,
    Occasionally, when using a NavMeshAgent on a NavMesh, the player stops moving because he is blocked from completing his move to setDestination(). At this point, the player's animation remains walking, however, I would like it to set to idle at this point.

    How can I find out if a navMeshAgent is not physically moving but the animation walk is still active? Or something along these lines.
     
    DBarlok likes this.
  2. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Check how far the NavMeshAgent moved since the last frame. Like that you can compute the speed. If it is below a certain value, you play the idle animation, otherwise the walk animation.
     
    DBarlok likes this.
  3. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    M-A-N, DBarlok, art092 and 2 others like this.
  4. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    DBarlok likes this.
  5. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Fair point. I checked for my own curiosity because I didn't know - and I only have 3000 posts :)
     
    DBarlok likes this.
  6. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,680
    Yah yah yah.
    Merci boucoup!
    I do appreciate.
     
    DBarlok and 77518189 like this.
  7. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,680
    I cant seem to get it to work. I hate Mondays.

    I have tried comparing lastPos to currentPos, remaingDistance to lastRemainingDistance and if velocity is 0. All catch a point in a path where this is true, despite it not being the desired effect. The result is a moving agent, with an idle animation.


    Line 22 should be the point of interest.
    Code (csharp):
    1.  
    2.         ///TAP FOR MOVE  
    3.         if(Input.GetMouseButtonDown(0)){
    4.               Ray ray = Cam_Main.ScreenPointToRay(new Vector3(Input.mousePosition.x, Input.mousePosition.y + 7.1f, -18.6f));
    5.               Vector3 dir = new Vector3(ray.direction.x * 100, ray.direction.y * 100, ray.direction.z * 100);
    6.             RaycastHit hit;
    7.             if(Physics.Raycast(ray.origin, dir, out hit, groundsLayerMask)){  
    8.                 moveToPos = hit.point;//new Vector3(hit.point.x, hit.point.y, agent.transform.position.z);
    9.                 dist = Vector3.Distance(agent.transform.position, moveToPos);
    10.                 agent.SetDestination(moveToPos);
    11.                 agentAnimator.SetFloat("Speed",0.2f);//make anim move
    12.                 movementActive = true;
    13.               }
    14.         }
    15.      
    16.         if(movementActive){
    17.             dist = Vector3.Distance(agent.transform.position, moveToPos);
    18.             if(dist < 0.02f){
    19.                 agentAnimator.SetFloat("Speed",0f);//make anim move
    20.                 movementActive = false;
    21.             }
    22.             if(lastDist == dist && agent.velocity.x == 0 && agent.velocity.z == 0){
    23.                 agentAnimator.SetFloat("Speed",0f);//make anim move
    24.                 movementActive = false;
    25.             }
    26.          
    27.             lastDist = dist;
    28.         }
    29.  
     
    DBarlok likes this.
  8. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    Some ppl are about quantity ;)
     
    DBarlok and DustinBoyle like this.
  9. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    You don't need movementActive from my point of view.

    Code (csharp):
    1. float velocity = agent.velocity.magnitude;
    2. if (velocity > someMovementSpeedThatMakesSense) {
    3.     agentAnimator.SetFloat("Speed",0.2f);
    4. } else {
    5.     agentAnimator.SetFloat("Speed,0f);
    6. }
    Like that you can get rid of everything after line 16, as well as 11 and 12.
     
  10. MammothEmpire

    MammothEmpire

    Joined:
    Jul 2, 2017
    Posts:
    1
    thanks, just randomly looked for a solution to animate a character and this fixed all the problems i had.
     
    DBarlok likes this.
  11. sarahnorthway

    sarahnorthway

    Joined:
    Jul 16, 2015
    Posts:
    78
    User Tryz posted a thorough solution here that takes path existence, proximity and velocity into account:
    https://answers.unity.com/questions...ts-dest.html?childToView=746157#answer-746157

    Their code:
    Code (CSharp):
    1.  // Check if we've reached the destination
    2. if (!mNavMeshAgent.pathPending)
    3. {
    4.      if (mNavMeshAgent.remainingDistance <= mNavMeshAgent.stoppingDistance)
    5.      {
    6.          if (!mNavMeshAgent.hasPath || mNavMeshAgent.velocity.sqrMagnitude == 0f)
    7.          {
    8.              // Done
    9.          }
    10.      }
    11. }
     
  12. DaniilAlpha

    DaniilAlpha

    Joined:
    Oct 22, 2019
    Posts:
    2
    Maybу it is easier to use just
    Math.Abs(agent.velocity.x + agent.velocity.y + agent.velocity.z) < .05
    ?
     
    DBarlok likes this.
  13. DBarlok

    DBarlok

    Joined:
    Apr 24, 2013
    Posts:
    265
    You guys made my life easier.
     
  14. iamarugin

    iamarugin

    Joined:
    Dec 17, 2014
    Posts:
    862
    Code (CSharp):
    1. agent.velocity.sqrMagnitude > 0