Generating prefab navmeshes


#1

Hey, hope you’re doing well! Just purchased this and excited to try it out

So I generate at runtime a world from 20-30 prefabs. These prefab rooms are instantiated into the scene and connected with doors between them that can open / close as the player and other ai navigate

An example of a prefab:

My question is is it possible to create a recast navmesh for each prefab, save it, load it at runtime, and move it to be the same as the prefab’s location (aka moving the center of the navmesh bounds += the room’s position)? I’d like to avoid generating the graph at runtime if at all possible

Alternatively, I noticed you mentioning in another post generating a recast graph covering the entire world after instantiation in another post - I’m not sure that would work in our use case as we utilize dynamic room streaming to only stream in a few prefabs at a time

Ideally, we’d be able to stream in all the generated graphs at runtime, place them correctly, and then be done without having to worry about baking anything

However, if that is done, my next question is how would we be able to connect these graphs? I read about DynamicGridObstacles which seems would work for doors opening / closing on an existing graph, but probably wouldn’t work to connect two graphs. When using Apex Path we used portals, does similar functionality exist here?
Would we need to use AddNode in script??

Thanks so much!


#2

Hi

This is technically possible, it was in fact used in the (unfortunately discontinued) game Folk Tale. However it is not a use case that is supported easily out of the box. You would have to save the recast graph tiles using a script, and then load them at runtime using the RecastGraph.ReplaceTile method. It would also only work if the room tiles were of the exact same size.

As you are generating things during runtime, wouldn’t a grid graph not be more reasonable for you? As you use streaming, take a look at the example scene called “Procedural” which shows how to keep a grid graph updated in a small portion of the world and then efficiently move it around (e.g to follow the player character).


#3

Okay so I was a little bit leery of grids due to my past experiences…and the fact that we have a multilevel geometry

However, I am able to generate this multifloor grid in less than a second, props to your generation algorithm!!

However, my world is relatively large compared to the grid size so we’d either need to move the grid with the player, or use multiple grids
I can probably shift the grid to be centered on the player’s current room via script

My next question is what if I want entities that are far from the player to navigate, so I might need multiple grids…is it possible to navigate between grids if for instance they are touching?


#4

Ah. Yeah, large grid can be annoying to have to deal with.

There is no automatic connection of adjacent grids. I would recommend to use separate grids if you need navigation for units far away too, or they may overlap if they are somewhat close, but not so close that you could just use a single grid. It is possible to connect nodes via script, but for simplicity I would recommend keeping them separate. Also see this tutorial for how to force an agent to use a specific graph, which might come in handy (https://arongranberg.com/astar/docs/multipleagenttypes.html).

There’s an included script for that called the ProceduralGridMover.

Another solution which may or may not work for your game is to generate the navmesh for the whole world (using a recast graph) at load time (or at design time if possible) and then just use that. So the navmesh for the whole world could be loaded even though only a small part of the world geometry is streamed in for the player.
If having the whole world loaded at a single time is problematic, you could do it by loading in a chunk of the world, then recalculating the graph there, and then load another chunk and recalculate the graph there, and so on until the whole graph is scanned. This might add up to some loading time though (hard to say without knowing how large your graph is). If you have a level editor of some kind you might be able to do this when saving the level (as time is not so critical at that stage) and then save the whole graph to a file as well (see https://www.arongranberg.com/astar/docs/save-load-graphs.php).


#5

Great call, may I just say that the grid loading is much faster than before so its making using grids much more feasible

So what I’m thinking of doing is by default having a grid that moves with the player. I would also like to be able to, if I desire, change the grid to a saved one for certain areas via entering a trigger (for an area, for instance, that has a larger enemy than normal so larger cells would be appropriate). I’ll have a PlayerGridService component that exposes the current grid graph, whichever it might be, and change on the fly

However this will require me to be able to save a few grids and link them to a prefab somehow. If I click “Save to file” does that save all the currently loaded grids? Or is there a way to only save an individual grid?

It would be nice to be able to create a grid as a scriptable object asset and then link it in a field somewhere, so I could directly reference a grid from a prefab - might be out of scope for this system, I wouldn’t mind taking a stab at it if it were technically possible

Another thing I am considering is (if possible) adding my own save / load component which can store / serialize a single grid and then on load position it correctly, I did something similar for the apex path grids to move and rotate them with a placed prefab

Thanks!! Your system has worked great so far, I have been able to convert 75% of our entities over to it without any trouble at all