Up to date

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

手動更改場景

有時候, 有必要更好地控制如何交換場景. 如上所述, 一個 Viewport 的子節點將呈現給它生成的圖像. 即使對於 "目前" 場景之外的節點, 這也適用. Autoloads屬於這一類, 但是一個實例在運作時新增到樹中的場景也是如此:

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)

要完成迴圈並將舊場景替換為舊場景, 開發人員可以選擇製作. 從視圖中刪除場景有很多策略 Viewport. 權衡涉及平衡操作速度和記憶體消耗以及平衡資料存取和完整性.

  1. 我們可以刪除現有場景. SceneTree.change_scene()SceneTree.change_scene_to() 會立即刪除目前場景. 不過開發者也可以刪除主場景. 假設根節點的名字是 "Main", 可以執行 get_node("/root/Main").free() 來刪除整個場景.

    • 解除安裝記憶體.

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

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

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

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

    • 處理停止.

      • 好處: 沒有節點意味著沒有程序, 物理過程或輸入處理. CPU可用於處理新場景的內容.

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

  2. 我們可以隱藏現有場景. 通過更改節點的可見性或碰撞偵測, 我們可以從遊戲角色的角度隱藏整個節點子樹.

    • 記憶仍然存在.

      • 好處: 如果需要, 仍然可以存取資料.

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

      • 壞處: 更多資料被保存在記憶體中, 這將成為對記憶體敏感平臺(如Web或移動裝置)的問題.

    • 處理繼續.

      • 好處: 資料繼續接收處理更新, 因此場景將不斷更新其中依賴於差異量時間或影格資料的任何資料.

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

      • 壞處: 現在CPU的注意力分散在兩個場景之間. 負載過大可能導致畫面播放速率降低. 應該確保測試性能, 以確保目標平臺能夠支援它們提供的負載.

  3. 我們可以從樹上刪除現有的場景. 給現有場景的根節點分配一個變數. 然後使用 Node.remove_child(Node) 來將整個場景從樹上分離.

    • 記憶仍然存在(與從視圖中隱藏它相似的優點/缺點).

    • 處理停止(類似於完全刪除它的優點/缺點).

    • 好處:這種形式的“隱藏”更容易進行顯示/隱藏。人們必須只呼叫一個方法 add / remove_child 方法,而不是潛在地追蹤場景的多個變化。它類似於在其他引擎中禁用遊戲物件。

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

在有些情況下, 人們可能希望有許多場景同時存在. 也許人們在運作時新增他們自己的單例, 或者在場景變化之間保留一個場景的資料(將場景新增到根節點).

get_tree().root.add_child(scene)

也許他們希望使用 ViewportContainers 來同時顯示多個場景。這意圖是在螢幕的不同部分渲染不同內容的情況下是最理想的。迷你地圖和多人分屏遊戲就是很好的例子。

每個選項都有最合適的情況, 因此必須檢查每個選項的效果並確定最適合其獨特情況的路徑.