Up to date

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

將更改推送 (Push) 到遠端

前言

在大多數遊戲中,或多或少都會希望能夠中斷遊戲去幹些別的,例如休息一下或者修改選項。要非常細緻地控制哪些可以暫停(哪些不可以)實作起來非常麻煩,所以 Godot 提供了一個簡單的暫停框架。

如何暫停工作

要將遊戲暫停,就必須設定暫停狀態。將 SceneTree.paused 屬性賦值為 true 即可:

get_tree().paused = true

這樣做會導致兩件事。首先,所有節點的 2D 和 3D 物理都會停止。其次,根據處理模式的不同,某些節點的行為會停止或者開始。

備註

遊戲暫停時,可以通過 set_active 方法啟動物理伺服器。

處理

Godot 中的節點都有“Pause Mode”(暫停模式)定義它們應該在何時進行處理。可以在屬性面板中 Node 的屬性裡找到並修改。

../../_images/pausemode.webp

你也可以通過程式碼來修改該屬性:

func _ready():
    process_mode = Node.PROCESS_MODE_PAUSABLE

各個模式對節點的要求是這樣的:

  • Inherit(繼承) :處理與否取決於父、祖父等等節點中第一個具有非 Inherit 狀態的節點。

  • 可暫停:僅在遊戲未暫停時處理節點(及其繼承模式下的子節點)。

  • WhenPaused*僅*當遊戲暫停時處理節點(及其處於繼承模式的子節點)。

  • Process(處理) :無條件處理節點(以及 Inherit 模式的子節點)。無論暫停與否,該節點都會進行處理。

  • 禁用:節點(及其繼承模式下的子節點)根本不會處理。

預設情況下,所有節點的這個屬性都是“Inherit”狀態。如果父節點也是“Inherit”,那麼就會去檢查祖父節點,以此類推。如果祖宗們都沒有更改過狀態,那麼就會使用 SceneTree 的暫停狀態。也就是說,在遊戲暫停時預設所有節點都會被暫停下來。節點停止處理時會發生不少事情。

_process_physics_process_input_input_event 函式都不會再被呼叫。不過訊號仍然是正常工作的,因此它們連接的函式也會執行,即便該函式的腳本是附加在暫停模式為“Stop”的節點上的。

動畫節點會暫停它們的目前動畫,音訊節點會暫停它們的目前音訊流,粒子也會暫停。遊戲不再暫停時,它們都會自動繼續運作。

請注意有一點非常重要,即便遊戲暫停時節點仍在進行處理,但物理預設是**無法**正常工作的。如前文所述,這是因為物理伺服器會被關閉。遊戲暫停時,可以通過 set_active 方法啟動物理伺服器。

Pause menu example

Start by creating a button that will be used to pause the game.

Create a menu containing a close button, set the Process Mode of the menu's root node to When Paused, then hide the menu. Since the process mode is set to When Paused on the root node, all its children and grandchildren will inherit that process mode. This way, all the nodes in the menu will start processing when the game is paused.

Attach a script to the menu's root node, connect the pause button created earlier to a new method in the script, and inside that method pause the game and show the pause menu.

func _on_pause_button_pressed():
    get_tree().paused = true
    show()

Finally, connect the menu's close button to a new method in the script. Inside that method, unpause the game and hide the pause menu.

func _on_close_button_pressed():
    hide()
    get_tree().paused = false

You should now have a working pause menu.