Nav mesh components: Limitations and performance issues

Hi all!

I use the Unity Nav Mesh Components for fairly large nav meshs and a lot of agents.

I am facing two major problems, in brief:

  1. The calculation for paths takes very, very long.
  2. The number of simultaneously calculated paths seems to be limited.

Problem 1:
I have different map sizes, starting at 32x32 unity units. On this map size, the nav mesh works pretty well without any major problems. The largest size I currently have is 64x64, where it takes around half a minute on average to calculate paths. I actually plan to have larger maps but I currently can’t due to this limits. The picture shows the larger map.

I tried to do a lot of different things to get the complexity of the nav mesh down as much as possible and I think it’s not that bad compared to other meshes I see.

The problem might be that there are too many calculations pending, which leads me to the next problem.

Problem 2:
This is kind of connected to the first problem. During my tests, I gradually increased NavMesh.pathfindingIterationsPerFrame but I feel like this doesn’t change anything. Whether I set it to 500 (the recommended max.) or 10000, it doesn’t change anything in regards of calculation time.

I tried to set this value to crazy numbers just to test if the FPS would actually drain and maybe find a sweet spot or anything but I can still run the game with over 1000 agents on 30 FPS in editor, no matter how high I set this value. I assume there might be a max. set within the Nav Mesh Components.

As a solution I tried to only calculate partial paths and then, once an agent reached a partial destination calculate the next one and so on but this doesn’t work too well either.

The request:
So what I was wondering is if there are options to do the following:

  • Actually change the amount of paths being calculated per frame
  • Prioritize different calculations (this would help a lot already)
  • Multi-thread this entire thing (it’s not from my understanding)
  • Maybe have a way to reduce the mesh complexity

tl;dr:
What are the tricks and tips to get performance out of the nav mesh components?

If possible, I’d like to keep the Unity implementation of the nav mesh because changing that to something else (like the awesome A* project) would mean a lot of work and the amount of optimization I did with the unity stuff is fairly large.

Happy for all inputs and ideas!

Thank you!
Johannes

Hi! I’ve never had such long times calculating a path, but I can address some of your asks -
The Navigation System in Unity is already multithreaded via the jobs system under the hood - you can see this by checking out the Profiler (attached image)

You can reduce the NavMesh mesh complexity by overriding the voxel size on the NavMeshSurface to be something larger, which results in a less accurate mesh. If you set it too small Unity will warn you but will still bake a NavMesh.

The NavMesh.pathfindingIterationsPerFrame does impact the pathfinding calculation performance, but maybe it just isn’t solving your particular issues.

In terms of prioritizing different calculations - you could write some code to manage the when you call NavMeshAgent.SetDestination calls to prioritize specific agents if you have too many outstanding path calculations. NavMesh.CalculatePath also will return to you in a single frame a path, so that could be an alternative solution where you calculate paths and set the path of each agent instead of using SetDestination.

Hi! Thanks for your reply! =)

I already played around quite a bit with that but it has very little effect in my case, will try to reduce it further tho!

I actually would love to do this implementation because I feel like it would give me the most power to customize the system but if the path is returned in a single frame instead asynchronously taking a couple frames, doesn’t that mean it’s not multithreaded anymore?

Thank you again! =)

Yup - the calculation for each path would be single threaded. You may be able to job-ify the NavMesh.CalculatePath to get a similar result to what Unity is doing under the hood, but I’ve not tried that yet, it may give an error stating it can be only executed on the main thread. Other options would be to have a maximum number of paths to calculate per frame and calculate the paths in a Coroutine based on some queue

I’ll give it a try, thanks!

Implemented a simple queue yesterday which supports priorities. I limited it by number of paths per frame but also by calculation time (once the calculations took more than X milliseconds, the coroutine yields).

Still a bit messy and leading to issues but so far it looks potentially promising! =)

Ok, so here’s a little update. I made some valuable progress today but I am still stuck a bit.

First, I tried utilizing the Jobs system but as I never used it before, I came across a couple of problematic issues in my code design which made it very hard to add to the game. I also took some time to see how much processing the nav mesh really needs and it’s actually not that bad so I might not need it at all (max. of around 5 paths per frame on the largest map).

I made a simple scheduler which works nice and everything except for one big issue, which seems to be related to the nav mesh system itself. The paths are returned to the agents but at some point the agents just stop in place (see attached GIF).

I added a check that the paths’ status is indeed NavMeshPath.status == NavMeshPathStatus.PathComplete before assigning it to the agent so the paths must be complete. Still, the agents stop after a few units.

Any ideas on what’s going on are highly appreciated!

Thank you very much!!

(Sorry if this is written a bit clumsy, my brain is on the remaining 10% capacity after watching the profiler and debugger for a day lol)

7554571--934063--GIF 07.10.2021 17-17-45.gif

3 Likes

Hard to say exactly what is going on here but I think I see what you’re talking about.
In general debugging agents is kind of challenging because sometimes it’s your code, sometimes it’s something weird with the NavMesh, and sometimes it is actually a bug.

If you can reproduce it with very few agents I would recommend doing that, and logging all kinds of status information about your agents so you can pinpoint the state of it when it breaks to see better what is happening. Using the actual debugger is really challenging because you’ll need to check it every frame and it’s nearly impossible to tell which frame will break it unless you’ve pre-identified which state is the problem state.

Personally I’ve never run into this issue with agents just abruptly stopping so I don’t have much other guidance other than the general “debug and see what you can see” :frowning:

Absolutely. It only happens once there are a couple more agents around - imagine debugging 100 agents doing simultaneous stuff and keeping track. There are a couple of tricks but it’s time consuming as hell and it’s a worst case scenario. Will have to do it anyways lol

Anyways, thank you very much for your help! =)

Little update:

I narrowed everything down and I am pretty sure I found all issues which are Unity related. Everything else is due to my implementation.

The reason for the agents to stop waling was that the the auto-repath option does not disable repathing if a new obstacle is added to the mesh. In that case, the repath triggers and leads to the same issues I had in the beginning.

I removed all “dynamic” obstacles and it seems to work now.

3 Likes