OnApplication~の挙動

OnApplication~という名前のイベント関数が3つ用意されています。MonoBehaviourを継承したクラスに特定の名前のメソッドを作ることで自動的に呼び出してくれます。

  • OnApplicationFocus
  • OnApplicationPause
  • OnApplicationQuit

の3つがあります。

これらのイベントがどのような時に呼ばれるのか、いくつかのプラットフォームでどのようなときに呼ばれるのか調べてみました。
テスト用のコードは次のようにしています。

PC版ではログが実行中に見にくいので、適当なUIに文字列を出力していっています。ログが出る場合は、そちらを参照するだけで十分です。(PC版の場合は、exeの名前_Data/output_log.txtにログが出力されていきます。)
ClickQuitはボタンUIにつけてApplication.Quitを呼び出すためのものです。

Editor

Editor上でApplication.Quitを呼び出しても何の意味もないようです。ログから呼び出しを確認できましたが、実行が停止されることもなくそのままでした。

起動時(再生ボタンを押す)には以下のように表示されました。
OnApplicationPauseはポーズでないということでfalse、OnApplicationFocusはフォーカスされたということでtrueになっています。ポーズフォーカスの意味についてはここでは曖昧ですが、挙動を確認していくことで意味がわかってきます。

フォーカスについてですが、これはゲームビューが操作対象になっているということです。再生ボタンを押してから他の場所をクリックしていないか、最後にクリックした場所がゲームビューであればフォーカスされているということになります。
 
非常に微妙な違いですが、上のようにフォーカス時(左の図)とフォーカスされてない時(右の図)ではゲームビューのタブの色合いが違います。フォーカス時には多少明るくなっています。
フォーカスされているかされていないかが切り替わるときに、OnApplicationFocusが呼ばれていました。

ポーズはゲームが中断されるという意味で、実行がされなくなることです。エディターではRun In Backgroundの設定次第で挙動が異なります。

Run In Backgroundのチェックが付いてないときはエディター以外のGUIをクリックすればOnApplicationPauseでtrueとして呼ばれます。それで再びエディターをクリックして実行が開始されると、OnApplicationPauseでfalseとして呼ばれます。

Run In Backgroundのチェックが付いている場合は、実行が継続されOnApplicationPauseは呼ばれなくなります。

最後に再生ボタンを再び押して、ゲームの実行をやめると次のようになります。(Run In Backgroundの設定には関係しないようです。)このときはフォーカスが失われ、OnApplicationQuitが呼び出されています。

PC

プラットフォームをPCにしてビルドしたものを実行したときの挙動です。Windows上での確認になります。
基本的な挙動はEditorとほぼ同じでした。

異なる点はApplication.Quitが効き、このときにはOnApplicationQuitが呼ばれています。OnApplicationQuitはアプリをウィンドウ状態で開いたときに右上に出る閉じるボタンを押したときも呼ばれます。

起動時はエディターと一緒でした。

Run In Backgroundのチェックを付けないでビルドしたときは、OnApplicationFocusとOnApplicationPauseは引数が異なるだけで同じタイミングで呼び出されます。フォーカスされるというのは実行されていると同じだからでしょう。

Run In Backgroundのチェックを付けてビルドしたときは、OnApplicationPauseは呼ばれなくなりました。ウィンドウ以外のところをクリックすると、フォーカスが外れてOnApplicationFocusが呼び出されるというようにエディターと同じ挙動です。

またアプリの終了時にはOnApplicationFocusは呼ばれず、OnApplicationQuitのみが呼ばれていました。

Android

起動時には、OnApplicationPauseがfalseでOnApplicationFocusがtrueで呼び出されました。

ホームボタン(ナビゲーションバーの真ん中のボタン)、リセントボタン(ナビゲーションバーの右のボタン。正式名称はよくわかりません。)を押すと、OnApplicationFocusとOnApplicationPauseが引数の値違いで呼び出されます。アプリからシステムの方に行くと中断であり、アプリに戻るのが再開のようです。
最近のアプリ一覧の画面でアプリをフリックすれば終了させられますが、このときは何のイベントも呼ばれませんでした。つまり、OnApplicationPause、OnApplicationFocus、OnApplicationQuitのいずれも呼ばれずにアプリが終了させられるということです。

Application.Quitを呼び出してアプリの終了させた時には、OnApplicationQuitのみが呼ばれていました。

AndroidではOnApplicationQuitが呼ばれずに終了ができるので、重要なデータをOnApplicationQuitで保存するといった処理はまずい可能性があります。セーブすべきデータが更新されたら、なるべく早く保存すべきです。


このイベントの呼び出し順序が決まっているのかは不明です。ログを見るとタイミングは毎回同じような気がしますが、明言されてないのでわかりません。順番がどうであっても問題なく動くようにした方がいいですね。