暂停游戏与处理模式

前言

在大多数游戏中,或多或少都会希望能够中断游戏去干些别的,例如休息一下或者修改选项。要非常细致地控制哪些可以暂停(哪些不可以)实现起来非常麻烦,所以 Godot 提供了一个简单的暂停框架。

如何暂停工作

要将游戏暂停,就必须设置暂停状态。将 SceneTree.paused 属性赋值为 true 即可:

get_tree().paused = true

这样做会导致两件事。首先,所有节点的 2D 和 3D 物理都会停止。其次,根据处理模式的不同,某些节点的行为会停止或者开始。

备注

游戏暂停时,可以通过 set_active 方法激活物理服务器。

处理模式

Godot 中的节点都有“Pause Mode”(暂停模式)定义它们应该在何时进行处理。可以在检查器中 Node 的属性里找到并修改。

../../_images/pausemode.png

你也可以通过代码来修改该属性:

func _ready():
    pause_mode = Node.PAUSE_MODE_PROCESS

各个模式对节点的要求是这样的:

  • Inherit: Process depending on the state of the parent, grandparent, etc. The first parent that has a state other than Inherit determines the effective value that will be used.

  • Stop: If the scene tree is paused, pause the node no matter what (and children in Inherit mode). When paused, this node will not process.

  • Process: Even if the scene tree is paused, process the node no matter what (and children in Inherit mode). Paused or not, this node will process.

默认情况下,所有节点的这个属性都是“Inherit”状态。如果父节点也是“Inherit”,那么就会去检查祖父节点,以此类推。如果祖宗们都没有更改过状态,那么就会使用 SceneTree 的暂停状态。也就是说,在游戏暂停时默认所有节点都会被暂停下来。节点停止处理时会发生不少事情。

_process_physics_process_input_input_event 函数都不会再被调用。不过信号仍然是正常工作的,因此它们连接的函数也会执行,即便该函数的脚本是附加在暂停模式为“Stop”的节点上的。

动画节点会暂停它们的当前动画,音频节点会暂停它们的当前音频流,粒子也会暂停。游戏不再暂停时,它们都会自动继续运行。

请注意有一点非常重要,即便游戏暂停时节点仍在进行处理,但物理默认是无法正常工作的。如前文所述,这是因为物理服务器会被关闭。游戏暂停时,可以通过 set_active 方法激活物理服务器。

暂停菜单示例

这是一个暂停菜单的例子。创建一个弹框或者面板,里面放上控件,然后将其暂停模式设为“Process”并隐藏。将暂停弹框根节点设为“Process”后,它的所有子孙节点都会继承该状态。这样,场景树的这个分支就会在暂停时继续工作。

最后,当按下暂停按钮(任何按钮都可以)时,启用暂停并显示暂停界面。

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

要解除暂停,请在暂停界面关闭时执行相反操作:

func _on_pause_popup_close_pressed():
    $pause_popup.hide()
    get_tree().paused = false