I’m looking for a way to prune recast graphs to only include reachable areas in the resulting navmesh. We’re building our levels procedurally by stitching together prefabs. This causes walkable areas to be cut by walls and other obstacles. Which gives rise to navmesh areas that are unreachable. Is there any way to position “seed points” in the scene, and only keep recast regions that touch or can be reached from the this “seed point”.
I tried using the RelevantGraphSurface component together with the RecastGraph advanced option “Relevant Graph Surface”, but fail to understand how it works. If I place a single RelevantGraphSurface compoent in the scene, and then issue a scan. I get navmesh on either everything (when using the “Do not require” or “Only For Completely Inside” options) or just the navmesh area in the tile the component touches (when using the “Require for all” alternative).
Edit; forgot to mention that we’re on 5.1.6 PRO
Edit 2; if I disable tiles, the “Require for All” options seem to do what I want. We really want the tiles enable though
Hi there, I think there might be a lot of options here to get the desired activity;
Firstly, I’d take a look at PathUtilities.IsPathPossible and see if that’ll help your use case? That wouldn’t straight up remove the regions that can’t be walked to, but it could be used to check different areas, depending on the structure of your procedural levels?
As an aside, I’d recommend checking out the GraphNode and PathUtilities class documentation- there’s a lot of juicy options there that may help! GraphNode has a Walkablevariable that I’ve used for similar stuff, maybe take a look at that?
Failing that, GraphNode also has a Destroy() method that could be useful? Not sure how often you’re creating new graphs, but cycling through all nodes from the “seed point”, and seeing if it’s walkable or not, then destroying the ones that aren’t may be your solution?
Let us know if any of these ideas work for your use case!
Well I tried making a GraphModifier script, that hooks on the OnPostScan callback.
In this script I mark all nodes that are unreachable from a seed point as non-walkable using the Walkable property of the node. Unfortunately, this doesnt fully work. As soon as a NavmeshCut component is present in a tile, it will revert all nodes in that tile (regardless if they are affected by the cut) to walkable (as this was the initial value during the scan, which is where the cutting system caches the original tile data).
I also tried calling Destroy on the unreachable nodes. But as the documentation says, this should not be done from user-code. And indeed, it causes various issues where part of the code does not handle destroyed nodes (one such example is the GetContours method in GraphUtilities).
Hmm, can you send over a video or screenshots of how your world is generated? I could probably give a more case-specific idea with that info. Info/images on the interactions with the NavmeshCut would be valuable as well!
This is when a prefab with a NavmeshCut component is placed in the scene (notice the area behind the gray “wall”. The nodes are back to walkable again.
Despawning the obstacle reverts the old tile geometry, but not the nodes are still marked as walkable.
Regarding the issue with NavmeshCut causing untraversable edges in some cases look at the videos linked in my other thread (linked post and another a bit further down). This seem to happen at random (near tile edges) when I do full pruning with replacing tile content as per the previous posted link.
The main reason we want to prune the navmesh is to prevent random positioning of loot, mobs, etc to happen in areas that the player cant reach. We also use the navmesh to build a minimap where we dont want random islands all over the place.
Screenshot of one of our random levels without any pruning (to better illustrate why we want to reduce the mesh as much as possible, both for placement and our minimap)
Hey bumping this to make sure you found a fix for this since it’s been quiet for a bit? Apparently I had a reply loaded but never sent, possibly because I think we talked in another thread about you finding a solution? Is my memory correct there? Found this while looking for something else for you and want to make sure you’re good here
Yeah we went back to using a version of the solution posted here.
And it seem the culprit behind us having issues with the above solution was not really the pruning, but rather the issue with NavmeshCut causing parts of the graph to become disconnected (this thread)