【Godot】Process Modeによるポーズ機能の制御

作成: 2025-06-20最終更新: 2025-12-16

Godot Engineのポーズ機能とNodeのProcess Modeを解説。基本的な使い方から、ポーズされないUIの作り方、カットシーンやダイアログでの応用、パフォーマンスの注意点まで紹介します。

概要

ゲーム開発において、ポーズ機能はプレイヤーに一息つかせたり、設定を変更させたりするために不可欠な要素です。Godotには get_tree().paused = true という、ゲーム全体を簡単に一時停止させる機能が備わっています。しかし、「ポーズしたのにUIが操作できない」「一部のキャラクターが動き続ける」といった問題に遭遇することがあります。

その原因は Process Mode の理解不足にあることが多いです。この記事では、Godotのポーズ機能の基本から、それを自在に操るためのProcess Modeの概念、さらには高度な実装テクニックまでを解説します。

Process Mode設定画面

Godotにおけるポーズ機能の基本

Godotでゲームループの大部分を停止させるには、シーンツリーのpausedプロパティを操作します。

# シーンツリーを取得し、ポーズ状態を切り替える
func toggle_pause():
    get_tree().paused = !get_tree().paused

    if get_tree().paused:
        print("ゲームは一時停止しました。")
    else:
        print("ゲームを再開しました。")

get_tree().paused = true を実行すると、Godotは以下の処理を停止します。

  • _process(delta)_physics_process(delta) の呼び出し
  • 物理演算(衝突、重力など)
  • InputEvent の処理(一部を除く)

しかし、これだけでは「すべてのノード」が停止するわけではありません。どのノードがポーズの影響を受けるかを個別に制御するのが、Process Modeの役割です。

Process Mode:ポーズを制御する5つのモード

Process Modeは、各ノードがシーンツリーのポーズ状態(get_tree().paused)にどう反応するかを決定する設定です。インスペクタの Node > Process カテゴリから設定できます。

モード (Mode)挙動主な用途
Inherit (継承)親ノードの設定をそのまま引き継ぎます。これがデフォルトです。シーンの大部分のノード。特別な制御が不要な場合。
Pausable (ポーズ可能)get_tree().paused = true のときに処理を停止します。プレイヤー、敵、動く背景など、ゲームプレイの主要素。
WhenPaused (ポーズ時)get_tree().paused = true間だけ処理を実行します。ポーズメニュー、設定画面、ダイアログなど、ポーズ中に操作したいUI。
Always (常時)get_tree().paused の状態に関わらず、常に処理を続けます。シングルトン(オートロード)、BGM管理、オンライン通信など。
Disabled (無効)常にすべての処理(_process, _physics_process, _input)を行いません。一時的に無効化したいオブジェクトや、デバッグ用のノード。

重要なポイント: Inheritがデフォルトであるため、ルートノードのProcess Modeを変更すると、その影響はすべての子ノードに及びます。

実践的ユースケースとコード例

ユースケース1:堅牢なポーズメニューの実装

ゲームは停止させつつ、メニューUIは操作可能にする必要があります。

Step 1: ポーズ管理シングルトン (PauseManager.gd) の作成

# PauseManager.gd
extends Node

const PAUSE_MENU_SCENE = preload("res://ui/pause_menu.tscn")

var is_paused: bool = false
var pause_menu_instance: Control = null

func _unhandled_input(event: InputEvent) -> void:
    if event.is_action_pressed("pause"):
        is_paused = !is_paused
        get_tree().paused = is_paused

        if is_paused and pause_menu_instance == null:
            pause_menu_instance = PAUSE_MENU_SCENE.instantiate()
            get_tree().root.add_child(pause_menu_instance)
        elif not is_paused and pause_menu_instance != null:
            pause_menu_instance.queue_free()
            pause_menu_instance = null

このスクリプトを「プロジェクト設定 > オートロード」でシングルトンとして登録します。

Step 2: ポーズメニューシーン (pause_menu.tscn) の設定

  1. Controlノードをルートとしてシーンを作成します。
  2. ルートノードのインスペクタで、Node > Process > ModeWhenPaused に変更します。
  3. このシーンに「ゲームに戻る」「タイトルへ」などのButtonノードを追加します。

ユースケース2:カットシーンの実装

カットシーン中は、プレイヤーの操作を無効にしつつ、特定のキャラクターやカメラのアニメーションは再生し続けたい、というケースです。

# CutsceneTrigger.gd (Area3Dなどにアタッチ)

@export var animated_characters: Array[Node]
@export var animated_camera: Camera3D

func _on_body_entered(body: Node) -> void:
    if body.is_in_group("player"):
        start_cutscene()

func start_cutscene() -> void:
    get_tree().paused = true

    # カットシーンで動かすノードのProcess Modeを一時的に変更
    for character in animated_characters:
        character.process_mode = Node.PROCESS_MODE_ALWAYS
    if animated_camera:
        animated_camera.process_mode = Node.PROCESS_MODE_ALWAYS

    $AnimationPlayer.play("cutscene_animation")

func _on_animation_player_animation_finished(anim_name: StringName) -> void:
    if anim_name == "cutscene_animation":
        end_cutscene()

func end_cutscene() -> void:
    get_tree().paused = false

    # Process Modeを元に戻す(重要!)
    for character in animated_characters:
        character.process_mode = Node.PROCESS_MODE_PAUSABLE
    if animated_camera:
        animated_camera.process_mode = Node.PROCESS_MODE_PAUSABLE

よくある間違いとベストプラクティス

よくある間違いベストプラクティス
get_tree().pausedをどこでも呼び出すポーズ状態の管理はシングルトン(オートロード)に一任し、他のスクリプトからは直接操作しないようにする。
UIがポーズ中に固まるポーズ中に操作したいUIのルートノードのProcess ModeWhenPausedになっているか確認する。
Alwaysモードの多用Alwaysモードは本当に必要なノード(BGM、シングルトンなど)に限定する。多用するとポーズ中のパフォーマンスが低下します。
AnimationPlayerが止まらないAnimationPlayerがポーズと連動しない場合は、Process Modeの設定を確認してください。Pausableに変更することでゲームのポーズと連動して停止するようになります。

パフォーマンスと代替パターン

パフォーマンスに関する注意点

  • Alwaysは最終手段: Alwaysモードはポーズ中のパフォーマンスを低下させる可能性があります。
  • Disabledで賢く節約: 一時的に不要になるノードは、Process ModeDisabledに設定することで、CPU負荷を下げることができます。

代替パターン:get_tree().pausedを使わないポーズ管理

get_tree().pausedはシーン全体に影響を及ぼすため、より局所的な制御がしたい場合は、シングルトンに独自のポーズ状態フラグを持たせる方法もあります。

# Player.gd
extends CharacterBody3D

func _process(delta: float) -> void:
    if GameStateManager.is_gameplay_paused:
        return
    # ...通常の処理...

基本的にはGodot標準のget_tree().pausedProcess Modeでほとんどのケースに対応できるため、この代替パターンは特定の高度な要件がある場合にのみ検討すると良いでしょう。

まとめ

get_tree().pausedProcess Modeは、Godotの強力な機能です。この2つを正しく理解し、使い分けることで、ポーズメニュー、カットシーン、ダイアログ表示など、ゲームに必須の様々な状況をエレガントに実装できます。

  • ポーズの基本: get_tree().paused = trueでゲームの大部分を停止できる。
  • 制御の鍵: Process Modeでノードごとの挙動を細かく設定できる。
  • ベストプラクティス: ポーズ管理はシングルトンに集約し、UIのProcess ModeWhenPausedに設定する。
  • パフォーマンス: Alwaysモードの多用を避け、Disabledモードを賢く使う。