I have a game where the player can dig into large rocks that are spread around the level. As the player does this, these rocks get smaller. I would like the NavMesh Surface to update when the rocks get smaller, so the AI can move over the ground where the rocks were.
I am using NavMeshSurface.UpdateNavMesh() to do this. However, I have noticed that it updates the navmesh for the whole level. As I am only changing the size of one rock, this seems a bit of an overkill to me, and a needless hit to performance. Am I correct in thinking this?
If so, I would like to only update the navmesh around the rock that has changed, and leave the rest alone. I have made my own version of the UpdateNavMesh() function, but have not been able to get it working properly - the best I have achieved is to update the navmesh in a small area around the rock using Bounds, but the rest of the navmesh outside this zone disappears.
I think I am just redrawing the navmesh, but just in a much smaller area based around the rock. Here is my code - any suggestions would be greatly appreciated:
public AsyncOperation UpdateNavMesh_My_Set_Bounds(NavMeshData data, Bounds updateBounds, NavMeshSurface theNavMeshSurface, List<NavMeshBuildSource> theSources)
{
Matrix4x4 worldToLocal = Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one);
worldToLocal = worldToLocal.inverse;
var result = new Bounds();
var m = theSources[0].sourceObject as Mesh;
result.Encapsulate(GetWorldBounds(worldToLocal * theSources[0].transform, m.bounds));
NavMeshBuildSettings navMeshBuildSettings = theNavMeshSurface.GetBuildSettings();
navMeshBuildSettings.preserveTilesOutsideBounds = true;
return NavMeshBuilder.UpdateNavMeshDataAsync(data, navMeshBuildSettings, theSources, result);
}
Take a look at unitys NavMeshComponents package, when you have it, under the package manager there is going to be some button like “view examples”, download the example package and open it up, inside you will find an asset called “localNavmeshBuilder” which only builds a navmesh locally for an agent type and the entire navmesh components package is pretty unique in its own right. Note that the navmesh components and the native navmesh assets are not interchangeable, but once you get the hang of it it should be pretty straightforward to do what you want. I believe if you also use unity 2022 they just upgraded the package not long ago in a way that lets you migrate the old system to that new system.
Why not simply use NavMeshObstacles and change their properties at runtime? Perhaps you simply haven’t used these before and are understandably looking into runtime modification of the mesh itself. But if it’s performant enough these would probably be easier to work with, as their properties only need to be updated as the rock changes. It doesn’t need to know about the NavMeshSurface itself.