【Godot Engine】一時停止・終了確認ポップアップ

ポップアップ作成

Godot には何種類かポップアップが用意されていますが、自分でオリジナルのポップアップを作るのも簡単にできます。

f:id:erudoru:20180321005749p:plain

シーンを新規作成し、ざっくりこんな感じのポップアップダイアログを作成します。

f:id:erudoru:20180321000656p:plain

ポップアップスクリプト

ポップアップに以下のスクリプトを追加します。

func _enter_tree():
    # ツリーに追加された際に、「閉じる」で終了させない
    get_parent().get_tree().set_auto_accept_quit(false)

# Popup の about_to_show を connect
func _on_Popup_about_to_show():
    # ポップアップ表示時にシーンツリーを停止
    get_parent().get_tree().paused = true

# Cancel ボタンの pressed を connect
func _on_Cancel_pressed():
    # シーンツリーを再開
    get_parent().get_tree().paused = false
    hide()

# Ok ボタンの pressed を connect
func _on_Ok_pressed():
    # アプリを終了
    get_parent().get_tree().quit()

paused 中のボタン操作

SceneTree.paused に true を設定するとザ・ワールド並に全てが停止します。ポップアップもその例に漏れず、一切の操作を受け付けなくなっていまいます。そのため paused の影響を受けずにポップアップの操作を行えるように追加で設定が必要です。

ポップアップの Cancel ボタンと OK ボタンを押せる様に、それぞれのボタンのインスペクターから Pause に Process を設定して paused 対象外に設定します。

f:id:erudoru:20180321002119p:plain

アプリに組み込み

確認用アプリはシンプルに背景色 (ColorRect) を設定して、先に作成したポップアップシーンを追加します。

f:id:erudoru:20180320235536p:plain

アプリのルート Node に以下のスクリプトを追加します。

閉じる、バックグラウンド、バックキー押下 (Android) 時にポップアップを表示するようにします。

func _notification(what):
    var quit_type = [
        # 閉じる
        MainLoop.NOTIFICATION_WM_QUIT_REQUEST,
        # バックグラウンド
        MainLoop.NOTIFICATION_WM_FOCUS_OUT,
        # バックキー
        MainLoop.NOTIFICATION_WM_GO_BACK_REQUEST
    ]
    # ポップアップ表示
    if quit_type.has(what):
        $Popup.popup()

ポイントは $Popup.show ではなく $Popup.popup でポップアップを表示すること。show を使用すると ポップアップの about_to_show シグナルが呼ばれません。

バックキーの設定

このまま Android アプリをエクスポートすると、バックキー押下時に NOTIFICATION_WM_GO_BACK_REQUEST が呼ばれず、そのままアプリが終了してしまいます。

追加で Project > Project Settings > Application > Config から Quit On Go Back をオフにします。

f:id:erudoru:20180321004452p:plain

これで、Android でバックキー押下時に NOTIFICATION_WM_GO_BACK_REQUEST が呼ばれます。

設定オンでアプリが終了するのはいいのですが、せめて NOTIFICATION_WM_QUIT_REQUEST を呼んでほしいのですが、これが仕様なのかもしれませんが現在のところ何も呼ばれずそのままアプリが終了してしまいます。

動作確認

アプリ実行後、バツボタンやアプリをバックグラウンド、Androidであれば更にバックキーを押下するとアプリ終了確認ダイアログが表示されます。

f:id:erudoru:20180321004616p:plain

公式ドキュメント

Handling quit requests — Godot Engine latest documentation

Pausing games — Godot Engine latest documentation

追記

popup で表示すると、ポップアップの周辺をタップした際にポップアップが閉じられてしまう様です。モーダル表示にするためには show を使用する必要がありそうです。

そうなると about_to_show シグナルが呼ばれないため独自に表示メソッドを作成した方がいいですね。

# これは disconnect してしまう
func _on_Popup_about_to_show():
    get_parent().get_tree().paused = true

# 新規作成
# popup の代わりにこれを呼ぶ
func show_popup():
    get_parent().get_tree().paused = true
    show()