[UE4]MobileアプリがBackground化したらSaveする
概要
ユーザー操作やOS判断でアプリが終了された場合に備えるため、
Homeボタンや着信によって起動中のアプリがBackground化した時、アプリの状態をストレージに記録したい。
このページでは、UE4公式提供のActionRPGとUnreal Match 3を参考にしつつ
両者で使われていないPlatformGameInstanceを試した実装について記す。
Save機能について
GameInstanceにSaveGameオブジェクトを持たせる
ActionRPGとUnrealMatch3の両方でGameInstanceを拡張したC++クラスを使用しており、
それはSaveGameオブジェクトを保持している。
確認方法:
Project Settingsで「Game Instance」で検索して、プロジェクトに適用されているGameInstanceクラス名を得る。
その名前でContent Browserを検索するとBPが見つかるので、それを開く。
ツールバーでClass Settingsをクリックし、Detail窓でParent Classを確認する。
エディタで該当クラスの実装を開く。
SaveとかLoadとかのキーワードで検索してみる。
SaveGameそのものについては、ゲームを保存する - UE4公式ドキュメントに詳しい。
また、ほげたつ氏の記事UE4でゲームデータのセーブ/ロードも参照。
なぜGameInstanceに持たせるのか
たとえばLevelやGameModeに持たせることもできる。
しかしSave操作を行いたいLevelやGameModeすべてがSaveGameオブジェクトを持つ羽目になる。
GameInstanceならゲームを通して1つなので、SaveGameオブジェクトは1つで済む。
Background化の検知について
PlatformGameInstanceを使う
PlatformGameInstanceは、mobileの各種イベント検知機能が追加されたGameInstanceになっている。
ヒストリア様のブログ記事「[UE4]モバイル特有の動作のイベントを取得する」で行っている実装が既に済んでいるような感じだろうか。
あとは、実装済みのDelegateに任意のイベントをバインドすればよい。
ゲーム開始時に一度だけBindできればよいので、UnrealMatch3を真似てInit() と Shutdown() を overrideして関数をバインドする。(Match3GameInstance.cpp参照)
C++でバインドする場合
AddDynamicとRemoveDynamicで楽にバインドできる。
void UMyPlatformGameInstance::Init() { Super::Init(); this->ApplicationWillEnterBackgroundDelegate.AddDynamic(this, &UMyPlatformGameInstance::SaveEnv); // Bindした関数内で、SaveGameを使ってSaveする } void UMyPlatformGameInstance::Shutdown() { this->ApplicationWillEnterBackgroundDelegate.RemoveDynamic(this, &UMyPlatformGameInstance::SaveEnv); // もはやGameが終了するタイミングだが、後片付け実装の練習と習慣化のため Super::Shutdown(); }
BPでバインドする場合
これもInitとShutodownイベントをそれぞれ使えばよいだろう。
忘れずにProject Settingsに反映する
Project Settingsで「Game Instance」で検索して、作成したPlatformGameInstanceをアサインする。
私の環境だけかもしれないが、変更がPIEに反映されている状態でAndroid端末にLaunchすると反映されない事があった。
Projectを開きなおすと反映された。
余談
UnrealMatch3では、Background化とForeground化それぞれで同じGateノードを制御して
Analyticsセッションのタイムアウト判定と再起動を行っている。
常時接続のゲームは一定時間以上Background化するとタイトル画面に飛ばされる事が多いが、あれのようなものだろう
Save以外にもやる事は多そうだ…
以上