Up to date

This page is up to date for Godot 4.3. If you still find outdated information, please open an issue.

手動更改場景

Sometimes it helps to have more control over how you swap scenes around. A Viewport's child nodes will render to the image it generates. This holds true even for nodes outside of the "current" scene. Autoloads fall into this category, and also scenes which you instantiate and add to the tree at runtime:

var simultaneous_scene = preload("res://levels/level2.tscn").instantiate()

func _add_a_scene_manually():
    # This is like autoloading the scene, only
    # it happens after already loading the main scene.
    get_tree().root.add_child(simultaneous_scene)

To complete the cycle and swap out the new scene with the old one, you have a choice to make. Many strategies exist for removing a scene from view of the Viewport. The tradeoffs involve balancing operation speed and memory consumption, as well as balancing data access and integrity.

  1. Delete the existing scene. SceneTree.change_scene_to_file() and SceneTree.change_scene_to_packed() will delete the current scene immediately. You can also delete the main scene. Assuming the root node's name is "Main", you could do get_node("/root/Main").free() to delete the whole scene.

    • 解除安裝記憶體.

      • 好處: RAM不再拖累自重.

      • 壞處: 回到那個場景現在更加昂貴, 因為它必須再次載入回記憶體(需要時間和記憶體). 如果不久就回來是不必要的.

      • 壞處: 無法再存取該場景的資料. 如果不久就使用這些資料就不成問題了.

      • 注意: 通過將一個或多個節點重新附加到不同的場景, 甚至直接將其重新附加到 SceneTree, 可以將資料保存在即將刪除的場景中.

    • 處理停止.

      • Pro: No nodes means no processing, physics processing, or input handling. The CPU is available to work on the new scene's contents.

      • 壞處: 這些節點的處理和輸入處理不再運作. 如果不需要使用更新的資料, 則不成問題.

  2. Hide the existing scene. By changing the visibility or collision detection of the nodes, you can hide the entire node sub-tree from the player's perspective.

    • 記憶仍然存在.

      • Pro: You can still access the data if needed.

      • 好處: 無需再移動任何節點來保存資料.

      • Con: More data is being kept in memory, which will be become a problem on memory-sensitive platforms like web or mobile.

    • 處理繼續.

      • Pro: Data continues to receive processing updates, so the scene will keep any data within it that relies on delta time or frame data updated.

      • Pro: 節點仍然是組的成員(因為組屬於 SceneTree).

      • Con: The CPU's attention is now divided between both scenes. Too much load could result in low frame rates. You should be sure to test performance as you go to ensure the target platform can support the load from this approach.

  3. Remove the existing scene from the tree. Assign a variable to the existing scene's root node. Then use Node.remove_child(Node) to detach the entire scene from the tree.

    • Memory still exists (similar pros/cons as hiding it from view).

    • Processing stops (similar pros/cons as deleting it completely).

    • Pro: This variation of "hiding" it is much easier to show/hide. Rather than potentially keeping track of multiple changes to the scene, you only need to call the add/remove_child methods. This is similar to disabling game objects in other engines.

    • 壞處:與僅從視圖中隱藏它不同,如果場景中包含的資料依賴於時間差異量、輸入、群組或其他通過存取 SceneTree 才能得到的資料,則它將變為陳舊。

There are also cases where you may wish to have many scenes present at the same time, such as adding your own singleton at runtime, or preserving a scene's data between scene changes (adding the scene to the root node).

get_tree().root.add_child(scene)

Another case may be displaying multiple scenes at the same time using SubViewportContainers. This is optimal for rendering different content in different parts of the screen (e.g. minimaps, split-screen multiplayer).

Each option will have cases where it is best appropriate, so you must examine the effects of each approach, and determine what path best fits your unique situation.