ゲームとプロセスのポーズ

はじめに

ほとんどのゲームでは、休憩を取ったりオプションを変更したりするなど、何か別のことを行うために、あるタイミングでゲームを中断できることが望ましいです。何をポーズできるか (何がポーズできないか) をきめ細かく制御するのは多大な作業であるため、Godotにはポーズのためのシンプルなフレームワークが提供されています。

ポーズの仕組み

ゲームをポーズするには、ポーズ状態を設定する必要があります。これは SceneTree.paused プロパティに true にセットすることで行われます。

get_tree().paused = true

これを行うと2つのことが起こります。まず2Dおよび3D物理演算がすべてのノードが停止されます。次に特定のノードの動作は、プロセスモードに応じて停止または開始されます。

注釈

物理サーバーはゲームのポーズ中に set_active メソッドを使用してアクティブにすることができます。

プロセスモード

Godotの各ノードには、どのように処理するかを定義する「プロセス モード」があります。これはインスペクタのノードの Node プロパティで変更できます。

../../_images/pausemode.webp

コードを使用してプロパティを変更することもできます:

func _ready():
    process_mode = Node.PROCESS_MODE_PAUSABLE

各モードに応じたノードの振る舞いは以下の通りです:

  • Inherit: 親や祖先などの状態に応じたプロセス。最初の親(ルート)は何も継承していません。

  • Pausable: ゲームが一時停止されていない場合にのみ、ノード (およびInheritモードの子) を処理します。

  • WhenPaused: ゲームがポーズされているとき*のみ*、ノード (およびInheritモードの子) を処理します。

  • Always: 常にノード (およびInheritモードの子) を処理します。ポーズしているかどうかに関係なく、このノードは処理を行います。

  • Disabled: ノード (およびInheritモードの子) は常に処理されません。

デフォルトでは、すべてのノードは "Inherit" 状態になります。つまり親ノードに設定されている同じプロパティに応じて処理する (または処理しない) ことを意味します。親が "Inherit" に設定されている場合、祖父母がチェックされます。最終的に祖先に状態が見つからない場合、SceneTreeのポーズ状態が使用されます。これはデフォルトではゲームがポーズすると、すべてのノードが停止することを意味します。

_process_physics_process_input_input_event 関数は呼び出されません。ただし関数のスクリプトが現在処理されていないノードにアタッチされている場合でも、シグナルは引き続き機能しており、接続されている関数が実行されます。

アニメーションノードは現在のアニメーションをポーズし、オーディオノードも現在のオーディオ ストリームをポーズし、パーティクルもポーズします。ゲームのポーズが解除されると、これらは自動的に再開されます。

ゲームのポーズ中にノードが処理している場合でも、デフォルトでは物理演算が**機能しない**ことに注意することが重要です。前述したように、これは物理サーバーがオフになっているためです。物理サーバーは、ゲームのポーズ中に set_active メソッドを使用してアクティブにすることができます。

ポーズメニューの例

まず、ゲームをポーズするために使用するボタンを作成します。

閉じるボタンを含むメニューを作成し、メニューのルートノードの プロセス モード**を **WhenPaused**に設定し、メニューを非表示にします。ルートノードではプロセス モードが **WhenPaused に設定されているため、すべての子と孫はそのプロセスモードを継承します。こうすることでゲームが一時停止されたときに、メニュー内のすべてのノードが処理を開始します。

スクリプトをメニューのルートノードにアタッチし、前に作成したポーズボタンをスクリプト内の新しいメソッドに接続し、そのメソッド内でゲームをポーズしてポーズメニューを表示します。

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

最後に、メニューの閉じるボタンをスクリプト内の新しいメソッドに接続します。そのメソッド内でゲームのポーズを解除し、ポーズメニューを非表示にします。

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

これでポーズメニューが機能するようになりました。