背景
- 実機では、NRホームメニューからアプリ終了すると OnDestroy が呼ばれない
- Editor では OnDestroy は呼ばれる
- NRSDK 1.8.0, 1.9.3 で確認済
- アプリ終了時にセーブデータ保存したいので OnDestroy内で PlayerPrefs.Save() しているが、現状では保存できない
結論
- 以下スクリプトのように、どこかの Calc でポーリングして終了ボタンに OnDestroy をコールバック設定する
void Update() { #if !UNITY_EDITOR // まだ AddListener(OnDestroy) してない、かつ、NRHomeMenu が表示されたとき if (!mIsRegister_OnDestroy && NRKernal.NRExamples.NRHomeMenu.IsShowing) { // 実機では、NRHomeMenu からのアプリ終了時には Framework.OnDestroy() が呼ばれないので、自前で OnDestroy をコールバックにセットしておく // // TODO: Find("NRHomeMenu(Clone)") の部分がやや強引なので、より堅牢な実装にすべき // NRHomeMenu.Start で AddListener されるので、AddListener(OnDestroy) の方が早い(UnityEvent, NRHomeMenu.CreateMenu, AddListener(OnDestroy), NRHomeMenu.Start の順) // よって、実行順は Framework.OnDestroy → AppManager.QuitApplication() で保障される GameObject.Find("NRHomeMenu(Clone)").GetComponent<NRKernal.NRExamples.NRHomeMenu>().confirmBtn.onClick.AddListener(OnDestroy); mIsRegister_OnDestroy = true; } #endif } #if !UNITY_EDITOR private bool mIsRegister_OnDestroy = false; #endif
備考
- NRHomeMenu.IsShowing をポーリングするのは、NRHomeMenuが初めて表示されたときに NRHomeMenuオブジェクトが生成され、Find("NRHomeMenu(Clone)") できるようになっているため
- はじめは NRHomeMenuすら存在しないので、アクセスする方法がない(もちろん、NRSDKを修正しないという前提)
- ちなみに、NRHomeMenu以外のアプリ終了方法(ケーブル抜き、スマホ上でのアプリキル、などの強制終了)には対応していない
- 根本原因は NRDevice.QuitApp()
- Editor 以外の終了メソッド ForceKill が m_UnityActivity?.Call("finish") でUnity強制終了してしまっている・・・
- メモリ不足などの強制終了ではなくボタンからの正常終了なので、終了処理を挟めるようにしてほしいところ