Using NavMesh outside of Unity

I’ve been struggling for months on a pathfinding solution. Originally, I used Unity as my server as well as my client and I used NavMesh.CalculatePath() to calculate the paths for all of my NPCs and it worked very well. I then put my server on its own because it is going to be an MMORPG and, with so many worlds, I couldn’t possibly use Unity to keep track of everything in one scene. The Unity client has to remain dumb and it cannot make pathfinding decisions on its own unless it’s a path for my OWN character to get to another location and I’m telling the server each waypoint I want to walk to. NPCs, on the other hand, need to be controlled by the server, which doesn’t use Unity anymore.

I’ve tried other people’s systems and I tried implementing my own. The best I’ve seen so far is the A* Pathfinding system written by Aron Granberg. He’s a really nice guy from Sweden. The problem with the A* Pathfinding system is that baking takes considerably longer than Unity (at the same Voxel size, character radius, etc) and his system doesn’t work as well around lakes and other jagged geometry (that I’ve seen!)

Has anyone experimented with calling NavMesh.CalculatePath() from .NET outside of Unity? Within the UnityEngine’s .NET function, there is an internal call and I can’t get past that. If I can’t use Unity’s system directly, does anyone know of a fast pathfinding system that can take raw triangle information, including Navigation area tags? Or better yet, able to directly use a NavMesh.asset file?

Thanks in advance! :slight_smile:

Well first I’m always skeptical of people planning for mmo scale this far ahead. Just run multiple unity instances once you actually get there.

What I do is create scenes specifically for the server that contain the geometry for multiple actual zones or client scenes. Create meshes for your terrains if you need to and use those in place of the terrain. Use simple objects for the npc’s. You can run hundreds of npc’s this way covering a lot of mmo 'zone’s on a single unity instance.

Plus you want pathfinding client side anyways. Without it your npc’s will eventually get out of sync a bit, not make a corner or something, and then you are stuck using sucky approaches like warping them to correct things… Plus you can play other tricks like sending locations updates for the npc’s at much lower intervals, saving a ton of bandwidth. So the server is still in control of where the npc’s are going, but since you are using pathfinding you only need to send target location updates like once every half second or so instead of every 60ms. That’s a huge win with a lot of npc’s. And while it’s possible for server and client to calculate different paths, the distance is so short that any differences just aren’t noticeable by players.

I get around 500 npc’s per unity instance this way. Planning out your coordinate system so it works takes some work. I use just one big scene myself and dynamically load everything, and my server scenes are broken up in a grid layout with coordinates that match the larger world, so the server and client agree on everything.

What I’ve been trying to do is have a single multi-threaded process handle all maps for the entire server. I’m making lightning fast computations in combination of managed and unmanaged (C++) code.
I can understand your point about client-side pathfinding. The server can just say, “Hey, NPC with ID 23765476234 needs to move to xyz, you can take him to this destination along the shortest path”. But, this plan has holes. If a player isn’t there to witness the movement… say you leave and come back, the server wouldn’t know where to tell you the mob IS unless the server is also pathfinding. And, I don’t have to do updates every 60ms because the server just tells the clients where the NPCs’ destinations are for every waypoint. The server and the client simulate the NPCs movement to the next waypoint of the path and it’s proven to be very accurate. NPCs can’t get stuck on my levels because the server is 100% authoritative so, even IF a mob clipped a corner (which I have not seen), the client is going to just let it plow through to its destination.

As far as speed goes, I purposely randomly added thousands of NPCs throughout the world and had them move around and fight (some good, some evil). The CPU usage of the process never exceeded 18%. I could probably even get that lower if I used even less C# code…should’ve made it 100% C++.

If I can’t use Unity’s native code for pathfinding outside of Unity, I at least want to figure out how to use NavMesh.CalculateTriangulation() properly so I can use the A* Pathfinding system on a Unity navmesh. Unfortunately, CalculateTriangulation only spits out vertices and Navigation areas but withholds TILE information. If I had tile information, I can use A* with this data.

By client side pathfinding I mean’t in addition to server side pathfinding.

Thousands of npc’s calls for a different approach. If your central server handles all the core ai and you just use unity for pathfinding only, then a single unity instance can easily handle the pathfinding requests for a few thousand npc’s if you optimize it a bit. Just setup a simple udp communication between your central server and unity using localhost.

That’s what I did for a while, but I went back to running unity instances that actually run the whole ai, as that’s the only way you can really do smart ai that uses physics and pathfinding. I have dynamic objects in the world that the ai needs to be aware of and do LOS checks against, or even at times interact with. With this approach everything is just simpler and works better. I’d much rather solve the problem of managing multiple unity instances and doing some optimization to get as many npc’s as I can on a single instance, then solving it another way. Mostly because I’ve tried about every other way there is over the years and none of them really worked out well.