- Home /
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.
Answer by kubajs · Mar 17, 2017 at 10:00 PM
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;
}
}
Answer by D3Duck · Jan 10, 2016 at 12:15 PM
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.
While the root cause might be true, your solution is a horrible hack that is not recommended at all.
Answer by rickygow · Mar 20, 2016 at 04:31 PM
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.
Answer by kelvin_feng · Apr 26, 2018 at 02:44 AM
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
Answer by LightclawJL · May 26, 2017 at 05:13 AM
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[i], 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...