TheDuckCow / godot-road-generator

A godot plugin for creating 3D highways and streets.
MIT License
358 stars 18 forks source link

Save generated meshes to resources #109

Open TheDuckCow opened 1 year ago

TheDuckCow commented 1 year ago

Right now, whenever you open the editor scene or start the game (or even just switch from one scene tab to another, sigh), road meshes need to be generated on the fly. For a game already built around procedural world generation, this is not too much of a problem - but for other games where roads should be generated and then just made static, it would be ideal that these can be saved in a native format that is loadable from disk. This will also greatly reduce the burden of time delay when tabbing over to a scene, which right now can take some time to load if there are a lot of meshes present.

Apparently, this should be possible using https://docs.godotengine.org/en/stable/classes/class_arraymesh.html and saving to resource files.

From this post, at least one person suggested: You could make your own Resource type that generates the ArrayMesh based on the exported variables

TheDuckCow commented 1 year ago

See this reference here, where by we could utilize the editor plugin ability to define a custom build function, which refers to building of the game itself.

https://docs.godotengine.org/en/stable/classes/class_editorplugin.html#class-editorplugin-method-build

TheDuckCow commented 3 months ago

Looking into this further: We are actually not far off from being able to support this actually. If in code we set var debug_scene_visible:bool = true, this will add all nodes created by the plugin directly into the scene hierarchy. This includes the array mesh and collision mesh. If we save the file at that point, it will fact persist all the mesh data to disk. We can disable the plugin at this point, and the mesh data would still remain, which is basically what we want here.

So. In order to save the mesh resource, we need to add it to the scene hierarchy. But this also violates our initial principle of never exposing the RoadSegment to the editor directly, since it's not meant to be user manipulated.

Screen Shot 2024-06-11 at 5 58 08 PM

Options include:

Maybe there are more approaches. Both bullet points above would likely end up needing us to enforce that 1 RoadPoint = one child RoadSegment/mesh, which further means we should try to avoid any of the complexity of flipped directions of RoadPoints.

This task is relevant now because we also want to avoid having to recreate all geometry for instanced scenes, something we're running into some issues with recently (https://github.com/TheDuckCow/godot-road-generator/issues/169) due to rotations on RoadContainers not working well for curve offsets. If we can save the mesh geo to disk instead of regenerating it for saved scenes, we would mostly bypass this problem (well, it'd at least be under the rug).

TheDuckCow commented 3 months ago

FYI @bdog2112 that this conundrum has come up as I contemplate saved scenes actually persisting their data. I need spend some thinking time on this one, since it would potentially lead to a bit of a restructure.

TheDuckCow commented 3 months ago

Illustrating a fuller example, which also has the typically invisible (in the editor) RoadLanes. I really wish we had a way to lock nodes from code to help imply to users what not to mess with, but unfortunately the last time I looked into this, there was no canonical way to do so.

Screen Shot 2024-06-11 at 6 11 46 PM

One more edit: I guess we can lock the nodes being created, it might just not show up right away (I misread that before). It is a hack and no idea if it still works in godot 4.x: ln_child.set_meta("_edit_lock_", true) and also this doesn't prevent property changes, just translation changes (but the UI hint is as helpful as anything).

Other issue I realized could be a problem is that selection by clicking could get interrupted this way, I've notice some flickering already where the road mesh ends up selected instead of the closest RoadPoint.

TheDuckCow commented 3 months ago

Ok on further consideration, seems like we could actually have the best of a few worlds, but would need to do some experimentation.. and might not be as straightforward as the just "saving everything to the scene" approach: