個人的Unityおぼえがき 2024年7月14日号

ワタアメです。最近の気付きの備忘録です。

本文

  • Windows環境で、「Play中のものがの動いているか動いていないか」を判定したい場合はOnApplicationFocusではなくOnApplicationPauseを使った方がよさそう。
    (理由:OnApplicationFocusはUnityエディタ上では「Gameビューに対するフォーカスの切り替え」の際に呼び出される。InscpectorとかHierarchyとかConsoleとかを触るとフォーカスがGameビューから外れ、「Play中のものが動いているがフォーカスなし」の状態が発生してしまうため)

  • 1. Play中に「何らかのフローティングウィンドウ(Unityエディタのメインウィンドウから切り離されたウィンドウ)」をクリックする
    2. タスクバー、デスクトップ、Unityエディタ以外のウィンドウ等をクリックするなどしてUnityエディタのウィンドウを非アクティブにする
    3. 何らかのフローティングウィンドウをクリックしてUnityエディタをアクティブにする
    4. タスクバー、デスクトップ、Unityエディタ以外のウィンドウ等をクリックするなどしてUnityエディタのウィンドウを非アクティブにする
    という手順を踏むと、バックグラウンド動作を許可しない設定(Run In Backgroundがfalseの状態)でも非アクティブ状態で動作が続くという現象(不具合?)が発生する。
    この時、OnApplicationPauseは「12 (pause=true)」と「23 (pause=false)」のタイミングで呼び出されて、問題の「34」のタイミングでは呼び出されていないっぽい。
    また、バックグラウンド動作を許可しない設定の時のUnityの音声についても「12」のタイミングで停止し「23」のタイミングで再開されるが(それはそう)、「34」のタイミングでは停止しない。
    (どうやらバックグラウンド状態の判定に不具合がある?)

応用

バックグラウンド動作が無効の状態では、再生完了を含む停止状態や一時停止状態の時以外にも、再生中にバックグラウンドになった場合にもAudioSource.isPlayingがfalseになる。OnApplicationPauseから受け取った値を活用することで、falseになった原因が「再生停止や一時停止」と「バックグラウンド」のどちらであるかを識別することができる。

実装例

/*	isFinished:	判定対象が既に停止している(再生完了によって停止した場合を含む)、
					Stop()やPause()によって受動的に停止した場合はtrue
	audioSource:	判定対象のAudioSourceの参照
	isWindowPause:	OnApplicationPauseから受け取った一時停止状況を保管しているbool型変数	*/
bool isFinished = !audioSource.isPlaying && (Application.runInBackground || !isWindowPause);

これにAudioSourceのPlay()とかStop()とかPause()とかを呼び出す際に状態を保持する仕組みを併用すると「バックグラウンド処理が無効の環境下で再生完了をUpdateで検知する」といったことが可能になる。

環境

OS:Windows 10 Pro 22H2
Unity:2022.3.10f1

あとがき

実際のところ「応用」が本文だったりするけど、「本文」って書いてある方の内容もそれなりに重要かも。

いいなと思ったら応援しよう!