The CalculatePath doesn’t look like async because it’s not shapped like an async function but it is async under the hood, you just need to test the path status in a loop.
https://docs.unity3d.com/ScriptReference/AI.NavMesh-pathfindingIterationsPerFrame.html
The async function looks like it limits the # of NavMesh.CalculatePath’s per update loop.
For me the pathfinding cost varies drastically based on distance and number of obstacles between source and destination. Limiting the # of pathfindings per Update loops might be an OK way of handling the problem but still gives 2 issues.
1: If the path is complex it could still cause FPS drop (unless the limit is set really really low for worst case scenario)
2: Close monsters would have periodic pathfinding causing jerky motion (unless smoothed out with additional code).
Not sure if there is a way to make an async function that varies the # of NavMesh.CalculatePath’s based on loading… but that would be more ideal than a fixed number of calculations.
@daxiongmao I’m not sure if I need to calculate the path every Update or not. But that’s currently the way I get the monster to “aim” at it’s target. If I recalculate every 100ms the monster jitter rotates as it only updates it’s aim every 100ms. I considered moving over to a different system if the monster is close… but my game has traps and obstacles an such that the monsters navigate around. So even if you are close to the monster I still want to pathfind around those. I’m not sure of any alternative to pathfinding every Update. Open to ideas.
In any case I LOD’d the NavMesh.CalculatePath rate and it seems to work well.
This NavMesh.CalculatePath cost is another thorn in the side of getting a smooth game. Getting smooth visual motion is already difficult (impossible?) with Unity due to Time.deltaTime variation issues.
Yeah it does, which is pretty neat if you tightly control the calls to that function like it seems you are doing.
It looks like you got enough attention on this long standing issue and they’re fixing it! Bravo. I always took jerking motion for granted in Unity and never paid attention to it, after the first year. But yes you can always recognize a unity game from its uneven motion ![]()
I don’t know if it is related but I noticed that ECS tests are very smooth, maybe this is a solution?
Back to Unity navmesh, it is not showing much love from UT, that’s for sure, I thought they surveyed large pro customers and found out that nobody uses it, but since they have recently updated navmesh to run with jobs blazing fast, my guess is that they preferred to wait until that was completed before adding granular control.
Does this mean it’s not synchronous even though manual clearly states that it is?
https://docs.unity3d.com/ScriptReference/AI.NavMesh.CalculatePath.html
Which makes no sense at all.
Or do you mean that it starts # of threads and then blocks main thread waiting for them to complete?
This do make sense. But it’s still, a synchronous call, blocking the thread. This can be avoided.
Oh you’re right, the old calculatepath is still main thread. weird isn’t it that the haven’t made this one async and the navmeshagent is async.
Anyway, this guy navmeshed tens on thousands of agents with ECS, it’s very hard to setup but if you need that much power, you just gotta
https://github.com/zulfajuniadi/unity-ecs-navmesh
Yap, need an async mode.
Thumbs up for async mode.
Same here… Async would be great! Thumbs Up
There’s experimental NavMeshQuery API:
Interested methods:
BeginFindPath
UpdateFindPath
EndFindPath
It’s synchronous, but it can be used from jobs, which is a way to make it async.
Man unity needs to add this asap. Meanwhile, I hacked together a solution
IEnumerator SetAgentDestinationWhenReady()
{
agent.SetDestination(AgentTargetPosition);
while(agent.pathPending)
{
agent.velocity = (AgentTargetPosition - agent.transform.position).normalized * agent.speed;
yield return new WaitForEndOfFrame();
}
}
I’m just moving the agent in a more primitive way until the path calculation is done.
The agent was briefly stopping after each waypoint. Both velocity and desired velocity dropped to 0 for a few frames and this caused the agent to start accelerating again. So I found this solution. Hope this helps
I agree, we really need this!
Wow I had no idea, I thought I was just bad at coding my bots as some of them were doing exactly that every now and then, thanks a lot!
I disagree. Async would be a band-aid. Navmesh needs to be moved to another thread, where it can happily take 100ms to calculate a path without affecting the framerate one bit.
So it’s already 4 years and still no async, or did I miss something?
Thank you for this solution. I just hope async really considered as an official feature in future
Not Only Async but also return the OffmeshLinks too, not just a Vector3 List
I just found this thread when trying to figure out why pathEndPosition would not update after setting a new destination. This answered my question, but now my new question is what to do about it. I was following Unity’s suggestion in the docs to use a NavMeshAgent to lead around my characters that are driven by root motion.
A Simplest way may be that one could just create a bunch of NavMeshAgent at game start, but use them as non-movable/rotatable and DontDestroyOnLoad, and create a new singleton wrapper class to give access to these NavMeshAgent. You won’t use these NavMeshAgents to move, but you can calculate the path by the NavMeshAgents.
(If the singleton class gives a good interface, the one who is taking use of it don’t even need to “know” NavMeshAgent)