Applying NavMeshCuts offline, removing whole regions of navmesh

Hi – Curious if you have any advice about how we might be able to apply NavMeshCuts when we compute our graphs offline. For the most part we would like to use them for two purposes:

  • Placing a specific region of the graph into a different area. The idea would be to apply the cut in dual mode, and then place the cut geometry into a separate area.
  • Wholesale removing large regions from the graph. Similar to above, but we would place it in the Not Walkable area and not perform the cut in dual mode.

The former is essentially trying to do what Unity’s NavMeshModifierVolume does (https://docs.unity3d.com/Manual/class-NavMesh-ModifierVolume.html). The latter is similar, but putting the whole region in the NotWalkable area.

Using the RecastMeshObj component is possible, but doesn’t really do what we want: if we make a large invisible cube and make it Unwalkable, nodes are still generated in the interior of the cube. We would like to be able to modify all the nodes inside the cube (either changing the area, or removing it entirely).

I’m totally happy to just give it a shot, but it looks like some of the internal code in TileHandler uses work items, which in the past I’ve not been able to get to work when not in play mode… any guidance would be welcome.

Thanks!
Pete

Hi

Sorry for the late answer. During the Christmas holidays I haven’t checked this forum often.

Currently it is not possible to do this in editor mode as you have already discovered, however what you would do is to start the game so that navmesh cuts are applied and then save the graph to a file (or recalculate the cache). This should make it save the graph including the applied navmesh cuts.

I have plans for a component similar to NavMeshModifierVolume, however currently it is in a pre-alpha stage unfortunately.

No worries, I was away for a bit as well. Thanks for the suggestion. I will try that, but think we may have some trouble with the play mode workaround.

For the time being, since we don’t have much need for dynamic navmesh updates (I’m sure I’ll regret this eventually), what I may end up doing is using Unity’s Recast implementation to generate a navmesh, grab the triangulation using NavMesh.CalculateTriangulation, and then use that data with your package. That will allow us to use unity’s modifier volume, etc (and as a bonus will give us faster navmesh calculation times). This also opens the possibility of post-processing the data with something like Triangle (would like to see what more uniform tessellation/edge lengths would do to path quality).

My question for you: we could use either a plain NavMeshGraph or try to fill in a RecastGraph by setting “scanEmptyGraph=true”… is there any demo for how to use scanEmptyGraph (the comment reads " Useful if you want to replace the graph with a custom navmesh for example", which seems like what we’d like)? Looking at ScanAllTiles it looks doable but replicating it all in external code may take some doing… but if you have demo code I’d definitely use that!

Hi

Ok. I think you should be able to use a normal navmesh graph.
Don’t bother about the scanEmptyGraph toggle. That is mostly compatibility code from before the navmesh graph used the same base code as the recast graph. A navmesh graph essentially does that internally already.

If you decide that you want dynamic navmesh updates then you can use them just as well with a navmesh graph as with a recast graph. It was only pre 4.x that e.g navmesh cutting could only be used with recast graphs.

Oh that’s great, thanks for pointing that out! Without tiles, is it as efficient? I guess you just select & cut all the triangles that overlap with the cut’s bbox.

Thanks for the help.

It is not as efficient as it has to recreate all nodes on the whole graph. In theory it is possible to avoid creating new nodes for triangles that look the same after the cut, however this is not done currently.

Any update or progress on NavMeshModifierVolume plans?

Not right now unfortunately.

Hi @aron_granberg

Is there any news about this?

For my game, I want to create the resulting NavMesh in the editor, so the game only loads a cached file, no updates to runtime is needed.

To do so, I added a RecastGraph, only checked “Rasterize Colliders”. Then, on each walkable area, I put a GameObject on a specific Navigation Layer with a Box Collider to define the walkable area.

That works well so far. Now I have some Building on the walkable area which should be cut by a NavMeshCut. For testing purposes, I did the NavMeshCut bigger than the actual object. When pressing “Scan” the area is not cut. As far as I understand from this discussion, this is the current behavior, so I have to do that at runtime and then save it? (I’d love to have that possibility in the editor!)

Or maybe my approach is wrong, so I’ll explain that further here.

I have a building, which has a floor. That floor defines the whole walkable area with a Box Collider as mentioned above. Rooms in the building shall cut the NavMesh, so the agents can not walk through walls (I plan to start using the RichAi):

E.g. in this sample picture, the wall shall be cut out, so the agents can not enter the room. Alternatively, I can also cut out the whole room.

Is this approach correct?

Here is the setting for the graph:

Thank you!

Edit:

I just found out, I can use the GraphUpdateScene on the wall and turn of Apply on start (well, would not matter, since a script will delete all objects on the Navigation layer at runtime, leaving only the Navmesh in tact). I think, that I can use that way. :slight_smile:

Hi

Is there a reason you need to use navmesh cuts? If you are always doing it in the editor anyway then why not rasterize the colliders like the recast graph does by default?

Any updates on this?
For me the recastgraph generates large areas outside the playable space. It would be helpful if those could be removed by specifing a region similar to how it’s done with points in graphupdatescene

Hi

There has been no updates on this. Navmesh cuts are deliberately a runtime-only thing.

In the beta version I suppose you could create a large invisible collider outside your playable region and mark with as unwalkable with the RecastMeshObj component. (wouldn’t work in the non-beta because only in the beta are colliders treated as solid things).