From 323b47facf009707d9fd6399fed44430cefccaed Mon Sep 17 00:00:00 2001 From: kobewi Date: Tue, 18 Feb 2025 10:46:54 +0100 Subject: [PATCH] Add scene_changed signal to SceneTree --- doc/classes/SceneTree.xml | 12 ++++++++++++ scene/main/scene_tree.cpp | 3 +++ 2 files changed, 15 insertions(+) diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml index 77baef9d089..9a31492d201 100644 --- a/doc/classes/SceneTree.xml +++ b/doc/classes/SceneTree.xml @@ -58,6 +58,7 @@ 1. The current scene node is immediately removed from the tree. From that point, [method Node.get_tree] called on the current (outgoing) scene will return [code]null[/code]. [member current_scene] will be [code]null[/code], too, because the new scene is not available yet. 2. At the end of the frame, the formerly current scene, already removed from the tree, will be deleted (freed from memory) and then the new scene will be instantiated and added to the tree. [method Node.get_tree] and [member current_scene] will be back to working as usual. This ensures that both scenes aren't running at the same time, while still freeing the previous scene in a safe way similar to [method Node.queue_free]. + If you want to reliably access the new scene, await the [signal scene_changed] signal. @@ -312,6 +313,17 @@ Emitted immediately before [method Node._process] is called on every node in this tree. + + + Emitted after the new scene is added to scene tree and initialized. Can be used to reliably access [member current_scene] when changing scenes. + [codeblock] + # This code should be inside an autoload. + get_tree().change_scene_to_file(other_scene_path) + await get_tree().scene_changed + print(get_tree().current_scene) # Prints the new scene. + [/codeblock] + + Emitted any time the tree's hierarchy changes (nodes being moved, renamed, etc.). diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 4043eb55ac9..557fced85ed 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -1517,6 +1517,8 @@ void SceneTree::_flush_scene_change() { pending_new_scene = nullptr; // Update display for cursor instantly. root->update_mouse_cursor_state(); + + emit_signal(SNAME("scene_changed")); } Error SceneTree::change_scene_to_file(const String &p_path) { @@ -1784,6 +1786,7 @@ void SceneTree::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_interpolation"), "set_physics_interpolation_enabled", "is_physics_interpolation_enabled"); ADD_SIGNAL(MethodInfo("tree_changed")); + ADD_SIGNAL(MethodInfo("scene_changed")); ADD_SIGNAL(MethodInfo("tree_process_mode_changed")); //editor only signal, but due to API hash it can't be removed in run-time ADD_SIGNAL(MethodInfo("node_added", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("node_removed", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));