背景
- 実機では、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強制終了してしまっている・・・
- メモリ不足などの強制終了ではなくボタンからの正常終了なので、終了処理を挟めるようにしてほしいところ