Curious about the interest level before I commit the time to maintaining it on github, as we use this in an actively developed game.
It’s basically a C# wrapper around recastnavigation which includes detour crowd.
The navmesh tile building api works off a design of geometry input providers. Code anywhere in your game can mark a point or bounds as dirty, and the navmesh builder then notifies registered input providers. Those providers then have time to run their logic in jobs and register the current geometry for the dirty bounds. Once all providers have provided input the builder merges the input geometry and updates the affected tiles.
Building is several orders of magnitude faster then Unity’s building and can be done entirely in jobs or C# threads. Map size doesn’t impact build times either,only tile/cell size. It also works well with open world designs. You can have a single navmesh that spans your entire game and efficiently add/remove tiles in jobs as the world changes. Tiles are stored as byte arrays so you can persist those easily.
The navmesh itself is optionally double buffered, as it’s fairly lightweight memory wise. So the entire process of rebuilding and updating the navmesh is job friendly and requires no main thread synchronization.
High level support for most other things is non existant, it’s a low level api. No editor tooling, you want to figure out how to setup different areas and agent types you need to understand the recast api. It’s all exposed in C# but I have no intention of creating tools we don’t need for our games. I’m not even sure yet I have the time to support just maintaining it on github:)
Very cool stuff. High interest from me. It certainly fills a big gap Unity has right now. I will definitely check it out in my own projects and provide feedback (if you take the leap ofc)!
Pretty sure I will actually. The C++ side is already out in it’s own VS project I would just need to take the C# which is in it’s own namespace and move it into it’s own project. Figure out the best way to include unity.mathematics in a stand alone project like that, as we just link against what is in Library. Might just let people link that in themselves maybe.
The tricky part is actually how to handle native collection integration. I don’t want the core C# library to be Unity only and currently it’s not. Plus iterating on C# interop is painful in Unity. Currently the build system is all managed collections. It’s job but not burst friendly which isn’t the end of the world because the heavy part is in C++ anyways, but I’d like to fix that before releasing it.
The per frame performance sensitive stuff like pathfinding and the crowd I just pass pointers to C++ to fill in. So I have method signatures that take a NativeArray pointer or a managed array that I fix a pointer to for the call.
Nice! Yeah, separating things out from your own project is always tricky. The bright side is that now we have upm. So it should make it easier for both yourself and end-users to consume the extracted lib.
Getting closer to a release on this. Final touches on an ECS based build system that collects Unity.Physics geometry. Nice uniform approach that supports geometry level filters. There is a navmesh surface abstraction and the ECS system manages all of them.
Just need to finish up some more testing of the crowd stuff and then it should be ready.
The image here is basically a stress/fuzz test on building. Lots of layered height fields with a terrain collider and a bunch of mesh colliders at various rotations.
I think if you really want control and make this a useful library I would suggest keeping the baking of the navmesh in C++. But expose the data as unity.entities blob assets. And have all the runtime queries actually be implemented as bursted C# code.
This is for a game primarily so I’m solving for very specific problems. Porting to C# would be nice it just makes no business sense as it wouldn’t solve any pressing issues. Which are primarily better handling of frequent runtime updates. The crowd is mostly icing on the cake.
I put it up with some minimal info on how it works. As I noted in the README this is not just a drop in replacement. It’s more if it solves some of the same problems we hit, it might be a good option. Or just take parts of it that interest you. Whatever you find useful.
Just curious, the purpose for the included Unity.Physics is to bring things like Unity.Physics.Mesh and ConvexHull (among others) from internal to public?
Ah okay. Looks like I missed that part in the ReadMe and had to find out the hard way (right off the bat, I attempted to use the official Unity.Physics to replace the included one).
Also, I can’t seem to find the mentioned sample scene in the repo.
All it is is an EcsWorld and AiNavSurface component though. The first just has to be there in editor mode.
This is the surface component in my test scene.
Here is an in context pic of a mesh source configured as shared. If shared is unchecked it will just use the mesh from the attached mesh filter. This one has the region set to 0, unwalkable so it ends up removing the navmesh where it is.
Here is my shared mesh db. Save is just a cheap hack to set the asset dirty, make sure it saves. AddMesh is to add custom meshes you provide in the top inputes. AddPrimitives is a convenience to add the primitive types.
The issue I had with including a nice Unity.Physics terrain in a demo was that the whole system relies on feeding it optimized geometry. Our terrain colliders are all partitioned and the whole system is a bit much just to include. On a 4k terrain we have 8k colliders that we bake out at design time using entities binary serialization. With the binary serialization there really isn’t a penalty for large numbers. Loading it’s just one big stream that loads directly into unsafe pointers and batch instantiated entities.