【Godot】ゲームを一時停止するポップアップウィンドウの実装方法

この記事では、ゲームを一時停止するポップアップウィンドウを実装します。

最も簡単なポップアップウィンドウ

OS.alert() と書くとゲームを止めて、ウィンドウがポップアップ表示されます。

OS.alert("メッセージウィンドウ", "")

ただこれでは見栄えが良くないので、あくまでテスト用ですね。

ゲームを止めるには get_tree().paused に true を指定すると、ゲーム全体が停止します。ただ全部止まってしまうと解除できないので、ポップアップウィンドウはこの停止を無効にする設定をしておき、ウィンドウが閉じたら一時停止を解除する……という流れになるようにします。

ちゃんとした一時停止を実装する

動き回るオブジェクトを作成する

ゲームが一時停止されていることを確認するため、画面を動き回るオブジェクトを作ります。

例えば、Area2D ノード(シーン)を作成してスクリプトを以下のように記述します。

extends Node2D

var velocity = Vector2(200, 100)

func _ready():
    pass

func _process(delta):
    position += velocity * delta
    if position.x < 0:
        position.x = 0
        velocity.x *= -1
    if position.y < 0:
        position.y = 0
        velocity.y *= -1
    if position.x > 480:
        position.x = 480
        velocity.x *= -1
    if position.y > 320:
        position.y = 320
        velocity.y *= -1

オブジェクトが画面内を動き回るコードとなります。

ポップアップウィンドウ(シーン)の作成

次にポップアップウィンドウ(シーン)を作成します。

ノード構成は以下のようにしました

Dialog (Popup): ポップアップ(シーン)
  +-- FadeBg (ColorRect): 暗転用の板
  +-- Label: メッセージテキスト
  +-- Button: OKボタン

テスト用なので、テキスト内容やボタンテキストは最低限のものとなります。

このポップアップウィンドウを一時停止させないようにするため、Dialog ノードの Pause > Mode を Process に変更しておきます。

ボタンクリックのスクリプト

Dialogノードにスクリプトをアタッチして以下のように記述します。

extends Popup

func _on_Button_pressed():
    # ボタンがクリックされたらインスタンスを消す
    queue_free()

ボタン(Button)の pressed シグナルに _on_Button_pressed() を接続しています。
ボタンクリック時は hide() で非表示にするか、queue_free() でインスタンスを削除するか、好みがわかれそうですが、今回は削除する方法としました。

メインシーンからポップアップウィンドウを呼び出す

Mainシーンを作成して、動き回るオブジェクトとボタンを配置します。

実行イメージです。

Mainシーンにスクリプトをアタッチして以下のように記述します。

extends Node2D

# ポップアップウィンドウをプリロード
var Popup = preload("res://Dialog.tscn")

func _on_Button_pressed():
    # ポップアップウィンドウ呼び出し
    var popup = Popup.instance()

    # ポーズ開始。ゲームを止める
    get_tree().paused = true
    add_child(popup)

    # show_modal()だと正常に動かない…?
    #popup.show_modal(true)
    popup.popup_centered_ratio(1)

    # popup終了時に "_resume()" を呼び出す
    popup.connect('tree_exited', self, '_resume')

func _resume():
    # ウィンドウを閉じたときのコールバック
    var tree = get_tree()
    if tree:
        # ポーズ解除
        tree.paused = false 

ボタンの press() シグナルに _on_Button_pressed() を接続しておきます。

ポップアップウィンドウを閉じた場合に、”tree_exited” シグナルに “_resume()” を接続しています。
そして、”resume()” でポーズを解除するようにしています。

実行して一時停止と解除ができることを確認します。

サンプルプロジェクト

参考用にプロジェクトデータを添付しておきます。

参考