navmeshagent reaches destination but idle animation doesn't play

using UnityEngine;
using System.Collections;

public class SampleAgentScript : MonoBehaviour 
{

	public Transform target;
	NavMeshAgent agent;
	Animator animator;
	float dist;
	// Use this for initialization
	void Start () 
	{
		agent=GetComponent<NavMeshAgent>();
		animator=GetComponent<Animator>();
		dist=agent.remainingDistance;
	
	}
	
	// Update is called once per frame
	void Update () 
	{
		agent.destination=target.position;
		if(Vector3.Distance(agent.destination, agent.transform.position)<=agent.stoppingDistance)
		{
			if(!agent.hasPath||agent.velocity.sqrMagnitude==0f)
			{
				print ("at destination");
				animator.SetBool("Walking",false);
				
			}
			
		}
		animator.SetBool("Walking",true);
	}

}

I am wondering why the “idle” animation doesn’t play when the meshagent reaches the destination? I have an animator controller setup with two animations, Walk02 and Idle and a boolean parameter to switch between the two.

For now, I want the walking animation to play as long as the agent hasn’t reached the target destination, which it does. It’s the idle animation that doesn’t seem to play. I added the animator.Play statement to see if that would help.

Thanks

could you post an screenshot of your animator and the transition conditions that involve this bool variable?

5 Answers

5

Place this line animator.SetBool("Walking",true); above the ‘If distance’ statement.
So it will look like the following:

 void Update () 
         {
             agent.destination=target.position;
             animator.SetBool("Walking",true);
             if(Vector3.Distance(agent.destination, agent.transform.position)<=agent.stoppingDistance)
             {
                 if(!agent.hasPath||agent.velocity.sqrMagnitude==0f)
                 {
                     print ("at destination");
                     animator.SetBool("Walking",false);
                     
                 }
                 
             }
         }

If you do not do this, the bool will always be overwritten to true. No matter to what it was set before (With the distance check). If you think about it you will come to understand why it wasn’t working :slight_smile:

Good luck!
-Gijs

Thanks! I did happen to figure it out by moving the animator.SetBool("Walking",true); to the Start() method and put the If statements into their own method called in the Update() method. I am sure that I could leave the If statements where they are and it will still work, but it just looks better this way. I do see where my mistake was and had thought it was because I hadn't initialized the boolean Walking properly, which I guess technically is true. All worked out in the end, thanks for the help

I am going to assume that the ‘animator.Play’ calls are not doing anything and taking those out will not solve your issue.

Have you tried looking at the Animator window while the animation is playing to see what state it is in?

It is kind of difficult to help unless we know the way your animation controller is working.

Here are two screenshots of controller [link text][1] [link text][2] [1]: https://www.dropbox.com/s/csg985g34bul7rh/Idle.png?dl=0 [2]: https://www.dropbox.com/s/lbck3bufe35b6h9/Walk.png?dl=0

Thanks. I have two animations in my controller, Idle is the default and Walk. I have transitions between both of the them. I have a boolean parameter called Walking which is set to true by default.

I am not sure why the animator.SetBool(“Walking”,false); statement doesn’t seem to be executed as the animator.SEtBool(“Walking”,true); statement works, as the model controller plays the Walk clip as it moves towards the target position.

I think it’s either a logic problem, though the second animator statement works, or the agent hasn’t reached the target destination, though the If statement is supposed to check for that.

Maybe there is something else I am missing?

I have the animation playing properly now. I believe my problem was that I didn’t initialize the Walking parameter, so I placed some code in the Start function that does this.

I checked on the answers forum here for info on now the Conditions of the animator controller worked, particularly the Boolean type. Someone answered a question similiar to mine and explained that an animation would only transition to another state only when the condition was met, in the answered question’s case True.

I also moved the If statements from within the Update function into its own method, though I am sure that for my purposes this doesn’t make a difference.

In my case I set the transition condition to Walking set to false and with the code I now have, it works great!

Here is my new code

using UnityEngine;
using System.Collections;

public class SampleAgentScript : MonoBehaviour 
{

	public Transform target;
	NavMeshAgent agent;
	Animator animator;
	float dist;
	// Use this for initialization
	void Start () 
	{
		agent=GetComponent<NavMeshAgent>();
		animator=GetComponent<Animator>();
		dist=agent.remainingDistance;
		animator.SetBool("Walking",true);
	}
	
	// Update is called once per frame
	void Update () 
	{
		agent.destination=target.position;
		Check();

	}

	void Check()
{
	if(Vector3.Distance(agent.destination, agent.transform.position)<=agent.stoppingDistance)
	{
		if(!agent.hasPath||agent.velocity.sqrMagnitude==0f)
		{
			print ("at destination");
			animator.SetBool("Walking",false);
			
		}
		
	}
}

}

Thanks all

You are calling animator.SetBool("Walking",true) every time in Update function, so it never will go to idle.

You should do something like that:

 void Update () 
 {
     // first if from you code
     // should be here
     // add new else after like here
     else if (Vector3.Distance(agent.destination, agent.transform.position) > agent.stoppingDistance) 
        animator.SetBool("Walking",true);
 }