Unity Navmesh in 2023 : maybe not what you want
Tags: unity3d, gameai, gamedev
Published: 2023-10-19 07:22:02

_I decided to give the Unity Navmesh a try mainly because I wanted a standard solution, and path-finding was not my immediate focus. When thinking navigation it's easy to forget that often, we need more than just going from A to B. They forgot (more likely, decided a comprehensive API would not perform blitz fast, therefore was not worth building)._

**How to use it**

At first glance the Unity navigation API is easy. Pretty much all you need to do is bake your navmesh and invoke `nma.destination = P`, where P is where you want to go and `nma` a `NavMeshAgent`. 

Could it be more simple?

You'll want to not move and rotate while no walk animation is playing:

```
// on start, and when exiting a walk animation
nma.isStopped = true;
// when entering a walk animation
nma.isStopped = false;
```

There are methods to disable updating the rotation/position of the agent. As a quirk these do not stop consuming the path - the position along the path keeps updating in the background.

The main goal of this post is helping you decide whether you should roll your own (not so hard) or go with Unity navmeshes.

There is good stuff. You can assign colors and costs to navigation areas, and the API lets you build connectors for laddering, crouching and such. 

**Not so good out of the box**

Let's be clear, you're not getting a great result out of the box, here's a few things you will notice:

- Paths are not very smooth; you get angular paths with semi-rounded corners
- Rotation is vehicular; not the hardest thing to fix but, regardless of your set rotation speed, the apparent rotation of an agent tends to desync from their motion direction.
- Choose between hugging walls and not passing through doorways; by default agents will take the shortest path. If you want margin between walls and agents, well you can't have that unless messing with areas and masking, or raising the baking radius.
- No straight answer to whether pathing has failed; used via `nma.destination=P`, `nma.pathStatus` does not show anything relevant. Now, you can calculate an arbitrary path and get a meaningful answer for that, however the method (`CalculatePath`) is synchronous.

The *actual* navmesh API will help with many of these. Is it more work? Absolutely. So the question is...

**Is it worth the effort?**

Getting to the meat, here's a couple of limitations that you should really keep in mind, because you may not want to design workarounds for every problem.

- Each agent have their own radius, however this only applies to *obstacle* avoidance. If your agents really have significantly different sizes, this isn't going to work, and again you'll end up messing with areas and masking, which aren't the correct answer to this.
- The navigation goal must be a point. There are plenty use cases where this is really awkward. What if you want to just avoid a number of agents? What if you want to reach any transform matching a given crit? What if you just want to keep moving roughly in a given direction?

With a general purpose search algorithm, none of the above is hard. It would seem that Unity navmeshes were designed mostly just to help enemies run towards the player, without care for the many use cases that this does not cover.

**Conclusion**

Overall Unity navmesh pathfinding is a mixed bag. The ease of use does not go very far, and you'll have to put in more work to get a nice result. At the core it's also a path-to-point system, which does get old quickly if you need to do anything (actually not) fancy.