ポップアップ作成
Godot には何種類かポップアップが用意されていますが、自分でオリジナルのポップアップを作るのも簡単にできます。
シーンを新規作成し、ざっくりこんな感じのポップアップダイアログを作成します。
ポップアップスクリプト
ポップアップに以下のスクリプトを追加します。
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 対象外に設定します。
アプリに組み込み
確認用アプリはシンプルに背景色 (ColorRect) を設定して、先に作成したポップアップシーンを追加します。
アプリのルート 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 をオフにします。
これで、Android でバックキー押下時に NOTIFICATION_WM_GO_BACK_REQUEST が呼ばれます。
設定オンでアプリが終了するのはいいのですが、せめて NOTIFICATION_WM_QUIT_REQUEST を呼んでほしいのですが、これが仕様なのかもしれませんが現在のところ何も呼ばれずそのままアプリが終了してしまいます。
動作確認
アプリ実行後、バツボタンやアプリをバックグラウンド、Androidであれば更にバックキーを押下するとアプリ終了確認ダイアログが表示されます。
公式ドキュメント
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()