nav remaining distance wrong

I have problem with nav remaining distance. I have code like this:

void Attack(){
			nav.SetDestination (player.transform.position);
		Debug.Log (nav.remainingDistance);
			if (nav.remainingDistance<0.4f) {
			gameController.LoseGame ();
				}

I’m trying to see what’s wrong by debug.log. Sometimes everything work. But sometimes nav.remainingDistance is about 0.0… and after second it gets good value. My Enemy always start at the same place - my player too. Why it sometimes works, sometimes not? I was trying everything and I don’t know where is the problem.

In case you use coroutine, just put this somewhere to the top:

if (_agent.pathPending)
    yield return null;

Example of my simple coroutine:

private IEnumerator Patrol()
    {
        while (_patrolling)
        {
            if (_agent.pathPending)
                yield return null;

            if (_agent.remainingDistance < _agent.stoppingDistance)
            {
                SetNextWaypointAsTarget();
            }

            yield return null;
        }
    }

I found in some forum that it’s because it’s still Finding it’s path and doesn’t have it’s remaining distance yet. so you can use this instead

        //-- If navMeshAgent is still looking for a path then use line test
        if(navMeshAgent.pathPending)
        {
            dist = Vector3.Distance(transform.position, moveTarget.position);
        }
        else
        {
            dist = navMeshAgent.remainingDistance;
        }

but still a little messy with the pathPending, me just use the Vector3.Distance as every movement now, less buggy for my Classic Moba click-to-move.

For anyone seeing this, or in case you still have this question.

When SetDestination() is called, I found that remainingDuistance is NOT immediately updated. It takes a frame (maybe one Update() call?) to set this.

So the solution is to wait one frame with a Coroutine or break out of the Update() function or whatever else. Point being, one frame later the remainingDistance will be correct.

If anyone needs to get the remaining distance for something like geting the closest objective, you can use a code like this one:

    public Dictionary<string,float> getObjectsDist(){
        Dictionary<string, float> dic = new Dictionary<string, float>();
        NavMeshAgent agent = GetComponent<NavMeshAgent>();
        NavMeshPath path = new NavMeshPath();
        foreach (string key in lib.Way.Keys) //this was the dictionary with my targets transforms.
        {
            Transform trans = lib.Way[key];
            NavMesh.CalculatePath(transform.position, trans.position, agent.areaMask, path);
            float dist = 0f;
            for (int i = 0; i < path.corners.Length - 1; i++)
            {
                dist += Vector3.Distance(path.corners*, path.corners[i + 1]);*

}
dic.Add(key, dist);
}
return dic;
}
This function returns a Dictionary with a name and distance to it.
Basically, you can crate an empty path, use your navmesh to calculate a path between 2 transforms, and the you go corner from coner on it (so you iterate on each line on the final path) and sum all the distances, getting your final distance.
Hope it helps.
*Sorry for bad english…

While the player is stopped, the remainingdistance equals zero even you set the destination immediately.
After you set the destination, agent would set the pathPending true and spend times on find a path. So the remainingdistance would keep the old value at least one frame.You can have a try with blow code.

if(!agent.pathPending && agent.remainingDistance <= agent.stoppingDistance)
{
	gameController.LoseGame();
}

Cheers