Godot4 Androidスマホでアプリのオートセーブができない問題の対処法

前回、無料で軽快な 2D/3D ゲームエンジン GodotEngine4作成したタップゲームを Android スマートフォンに USB ケーブル経由でインストールしてデバッグ実行しました。
実機でデバッグ実行すると、PC では発生しなかった問題がいくつか発生しました。

スマホ実機でapk動作確認 インストールをタップして apk からアプリをインストールします...

今回は、無料で軽快なゲームエンジン GodotEngine4 で作成したアプリを Android スマートフォンの実機でデバッグ実行した際に、スコアなどのセーブデータがオートセーブされないバグとその対処法について紹介します。

※この記事の内容は、アプリ タップ The 宝箱 の開発でも使用しています。
※ GodotEngine のバージョンは 4.1.2 です。 .NET 版ではありません

※「いらすとや」様の画像を使用しています。
※「ふい字」フォントを使用しています。

※「魔王魂」様のサウンドを動画内で使用しています。
※「無料効果音で遊ぼう!」様のサウンドを動画内で使用しています。
※記事で紹介するスクリプト / プログラム / コードは自己責任で使用してください。

セーブとロードの実装について

セーブとロードの処理の実装については後日、別記事で紹介します。
今回は Android スマートフォンでデバッグした結果、セーブの処理自体が呼び出されない問題について対処します。

セーブ・ロードができない問題の対処

宝箱をタップしてスコアを増やしてから、一度アプリを閉じます。
再びアプリを起動するとスコアが初期値の 0 に戻っています。

Godot4 TapTheTakarabako オートセーブ失敗の例

原因の切り分け

オートセーブが動作していない原因として以下の4つが考えられました。

  1. セーブ処理自体が動作していない
  2. ロード処理が動作していない
  3. アプリが閉じられる際にセーブ機能が呼び出されていない
  4. アプリ起動時にロード機能が呼び出されていない

試しに、確実にイベント処理が行われているコインや宝石が飛び出す処理で、セーブ機能を呼び出すようにした apk を作成して実機デバッグを行うと、2回目の起動時に以前のセーブデータが読み込まれました。

このことから、3番の「アプリが閉じられる際にセーブ機能が呼び出されていない」が原因であることがわかりました。

アプリ終了に関するプロジェクト設定

メニュー「プロジェクト」→「プロジェクト設定」を選択して「プロジェクト設定」ウィンドウを開きます。
「一般」タブの「アプリケーション」→「構成」を選択します。

「プログラム終了を自動的に受け入れる」は既定値ではチェックされていますが、これを解除しないと NOTIFICATION_WM_CLOSE_REQUEST イベント通知を受け取れないようなので、チェックを解除します。

Godot4 TapTheTakarabako プログラム終了を自動的に受け入れる(auto_quit_accept)の設定を無効にします.

しかし、それだけではバグは修正できませんでした。
他サイト様「How to handle Android game closing in Godot 4? : r/godot」によると、スマートフォンによっていろいろな終了方法があり、終了を通知するメッセージを受け取れないこともあるようです。

そのため、アプリ終了のメッセージ以外、例えばバックグラウンドにアプリが隠れた場合などアプリ終了の少し前に置きそうなメッセージを受け取ったらセーブを行うようにしました。

修正前は、以下の3つのメッセージ ID が送られてきたらセーブ機能を呼び出していました。

# アプリ終了の条件とみなすメッセージ ID
var list_quit_message_id = [
	# 閉じる
	NOTIFICATION_WM_CLOSE_REQUEST,
	# バックキー (android)
	NOTIFICATION_WM_GO_BACK_REQUEST,
	# バックグラウンド
	#NOTIFICATION_APPLICATION_FOCUS_OUT,
]

修正後は、アプリがバックグラウンドに隠れた場合など、アプリ終了と直接関係しないイベント通知でもセーブ機能を呼び出すようにしました。

# セーブの条件とみなすメッセージ ID
# 終了処理のメッセージだけでは、 Android 実機では呼び出されないで終了することがあるため、別のメッセージでもセーブします。
var list_save_message_id = [
	# 閉じる
	NOTIFICATION_WM_CLOSE_REQUEST,
	# バックキー (android)
	NOTIFICATION_WM_GO_BACK_REQUEST,
	
	NOTIFICATION_APPLICATION_PAUSED,
	
	NOTIFICATION_APPLICATION_RESUMED,
	
	NOTIFICATION_APPLICATION_FOCUS_OUT,
	
	NOTIFICATION_APPLICATION_FOCUS_IN,
	
	NOTIFICATION_WM_WINDOW_FOCUS_IN,
	
	NOTIFICATION_WM_WINDOW_FOCUS_OUT,
	# バックグラウンド
	NOTIFICATION_APPLICATION_FOCUS_OUT,
]

以下は、前述したセーブする対象のイベント通知があればセーブして、アプリ終了のイベント通知があればセーブの後に終了処理を呼び出しています。

# セーブデータの保存先。 Windows の場合 user:// は %APPDATA%\Godot\app_userdata\プロジェクト名\ に保存されます。
var save_path = "user://TapTheTakarabako.save"


# セーブの条件とみなすメッセージ ID
# 終了処理のメッセージだけでは、 Android 実機では呼び出されないで終了することがあるため、別のメッセージでもセーブします。
var list_save_message_id = [
	# 閉じる
	NOTIFICATION_WM_CLOSE_REQUEST,
	# バックキー (android)
	NOTIFICATION_WM_GO_BACK_REQUEST,
	
	NOTIFICATION_APPLICATION_PAUSED,
	
	NOTIFICATION_APPLICATION_RESUMED,
	
	NOTIFICATION_APPLICATION_FOCUS_OUT,
	
	NOTIFICATION_APPLICATION_FOCUS_IN,
	
	NOTIFICATION_WM_WINDOW_FOCUS_IN,
	
	NOTIFICATION_WM_WINDOW_FOCUS_OUT,
	# バックグラウンド
	NOTIFICATION_APPLICATION_FOCUS_OUT,
]

# アプリ終了の条件とみなすメッセージ ID
var list_quit_message_id = [
	# 閉じる
	NOTIFICATION_WM_CLOSE_REQUEST,
	# バックキー (android)
	NOTIFICATION_WM_GO_BACK_REQUEST,
	# バックグラウンド
	#NOTIFICATION_APPLICATION_FOCUS_OUT,
]

# 通知イベントで呼び出されます。
func _notification(what):
	if list_save_message_id.has(what):
		# セーブデータを書き込みます。
		print("セーブします")
		save_app_data()
	if list_quit_message_id.has(what):
		# list_quit_message_id の要素のいずれかにあてはまる通知の場合は終了処理をします。
		# 既定ではプロジェクト設定>アプリケーション>構成のアプリケーションの終了を自動で受け入れる(auto_quit_accept)が有効なので
		# この処理は必要ありませんが、それを無効にしないと終了のメッセージが受け取れないため、無効にして終了処理を実装します。
		get_tree().quit() # default behavior
	return

User:// は Android で唯一の保存先で権限の追加も不要

今回のセーブ機能の修正の際に調べた有用な情報として

  • Android では User:// から始まるパスだけが保存先として利用できる
  • User:// から始まるパスへのファイルの保存には、 Android の権限を追加する必要がない
  • ファイルへのアクセス権限として Android では以下のものがありますが、どれも必要がない
    Read User Directory
    Write User Directory
    Read External Storage
    Write External Storage

ことがわかりました。
参照:「Godot・Tips」「How to save game progress on android? – Archive – Godot Forum

テスト

前回行ったように PC と Android スマートフォンを USB ケーブルで接続して、ファイル転送モードを選択した後、スマートフォンの内蔵ディスクのトップに、修正版の apk ファイルを上書きします。

Godot4 TapTheTakarabako Android 実機の apk ファイルを上書きします.

以前インストールしたアプリをアンインストールしてから、インストールします。

Godot4 apkインストール PCからコピーしたapkで新しくインストールする前にアンインストールします..

新しくアプリをインストールして起動します。

初回起動時に宝箱をタップしてスコアを増やし、音量も変更しました。
その後、一度アプリを閉じてから開くと、スコアと音量の設定がロードされました

Godot4 TapTheTakarabako オートセーブ成功の例

まとめ

今回は、無料で軽快なゲームエンジン GodotEngine4 で作成したアプリを Android スマートフォンの実機でデバッグ実行した際に、スコアなどのセーブデータがオートセーブされないバグとその対処法について紹介しました。
Android では User:// 以降のパスにのみファイルを保存できることや、特に権限を追加する必要がないこともわかりました。

参照サイト Thank You!

記事一覧 → Compota-Soft-Press

コメント

Ads Blocker Image Powered by Code Help Pro

お願い - Ads Blocker Detected

このサイトは広告を掲載して運営しています。

ポップアップを閉じて閲覧できますが、よろしければ

このサイト内の広告を非表示にする拡張機能をオフにしていただけませんか?

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

タイトルとURLをコピーしました