ブログ

NRホームメニューからNrealアプリを終了させても OnDestroy を呼ぶ方法

背景

  • 実機では、NRホームメニューからアプリ終了すると OnDestroy が呼ばれない
    • Editor では OnDestroy は呼ばれる
    • NRSDK 1.8.0, 1.9.3 で確認済
    • NRHomeMenu
  • アプリ終了時にセーブデータ保存したいので 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強制終了してしまっている・・・
    • メモリ不足などの強制終了ではなくボタンからの正常終了なので、終了処理を挟めるようにしてほしいところ

 

-ブログ

© 2022 墾田ええねん! Powered by AFFINGER5