Godot Version
4.2.2
Question
Hello developers, I’ve been trying to make something a little essential for one of my projects, the options menu, but I can’t find a way to delete the scene when it’s not being used.
I understand that I can simply hide the node, but I think a good way to save resources is to delete it, and for that reason I thought of doing something like this:
var options_menu = preload("res://src/menus/options_menu.tscn").instantiate()
func _on_options_pressed():
get_tree().root.add_child(options_menu)
options_menu.visibility_changed.connect(_options_visibility_changed)
func _options_visibility_changed():
options_menu.queue_free()
This would be the code present in the root scene and uses the mechanism of instantiating a scene, which I only use in the elements that can be used again, such as the levels and practically the player’s menu, but unfortunately it closes when trying to return to the scene and I’m not sure if it’s because it wasn’t completely removed, since that’s what I see in the API.
Would it be a better option to just hide it or should I try another method?
Specifically what error message are you seeing when the crash happens?
One issue I see here is that you don’t keep a valid reference to re-instantiate the scene after hiding the menu for the first time. If this was the way you wanted to do it, then first you would need keep a reference to the scene, i.e. var options_menu_scene = preload("path/to/scene") in addition to a var options_menu. In _on_options_pressed you would assign options_menu = options_menu_scene.instantiate(). The way it’s written right now, I believe you would run into an error if you pressed the options button, hid the menu, and then pressed the button again, as you tried to add an already-freed node as a child of the scene root node.
But it would probably be better to just change the queue_free to a .get_parent().remove_child(). I don’t think you’re getting a meaningful benefit from re-instantiating the scene each time. If the scene is actually large enough to have a serious impact on memory usage, I don’t think this would help. The whole thing is still being preloaded as this script runs.
The difference there is that in the code you shared you are deleting and invalidating the options menu outright upon it being hidden, whereas if you only removed it as a child, it would be kept around and still be usable again the next time the menu is shown, just not processed or updated since it would no longer be a part of the scene tree.