Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Save generated meshes to resources #109

Open
TheDuckCow opened this issue Jul 3, 2023 · 5 comments · May be fixed by #173
Open

Save generated meshes to resources #109

TheDuckCow opened this issue Jul 3, 2023 · 5 comments · May be fixed by #173
Labels
enhancement New feature or request
Milestone

Comments

@TheDuckCow
Copy link
Owner

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 TheDuckCow added the enhancement New feature or request label Jul 3, 2023
@TheDuckCow
Copy link
Owner Author

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
Copy link
Owner Author

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:

  • Forget our rule, and just tell users to avoid interacting with the RoadSegment class. We could also change its icon to a lock or something like this to help reinforce "don't touch me!"
    • Though this would still require changes, as each time the scene is loaded, duplicates get added as children - this is because the RoadSegment is named and fetched exactly after the id's of the two connecting RoadPoints. These ids are always going to be different at runtime. We'd need an entirely new road segment naming strategy.
    • This also means all of our AI lanes would need to be added to the scene as well. Would definitely make the scenes look more complex.. but admittedly, would also take away some of the curtain and show users what exactly is happening.
  • Move the array mesh object to be adjacent to the RoadSegment so it is added to the scene (the road_mesh node pictured above). Its collision mesh and such could also be there, which might be helpful for some users (though again hmm we might want to avoid users being tempted to interact with them, since they are recreated on rebuilds).
    • This would create a conflict though for cases where we end up with two segments as children of a single RoadPoint (which can happen if the direction of a RoadPoint flips within a stretch of a RoadContainer)
    • EDIT: this is not a real option if we want AI lanes and such to still be present in the saved scenes!

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 (#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
Copy link
Owner Author

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
Copy link
Owner Author

TheDuckCow commented Jun 12, 2024

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
Copy link
Owner Author

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:

  • Per this comment (updated docs location here), we could use _save_external_data to recreate objects if necessary and add them to the scene.
  • Then on scene open in the editor, we could see that the scene is being edited and clear out the nodes added in the scene tree.
    • Though this would make the scene always appear to be edited, unless we went to extra lengths to also update the _get_unsaved_status or maybe even/also _apply_changes, would need to play around to better understand which of these callbacks would be relevant and when before/after the actual saving happens they are called.

@TheDuckCow TheDuckCow linked a pull request Jun 20, 2024 that will close this issue
@TheDuckCow TheDuckCow added this to the v0.6.0 milestone Sep 9, 2024
@TheDuckCow TheDuckCow linked a pull request Dec 19, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant