Tips

【Unity】シーンの切り替えを検出するイベント
2018.10.24

【Unity】シーンの切り替えを検出するイベント

Unityのシーン切り替えを検出する


Unity5.4以降、シーンの管理・切り替え等はSceneManagerクラスで行っています。
関連:Unityのシーンを切り替える方法

そして、このSceneManagerクラスには、シーンの切り替えを検出するためのイベント(デリゲート)が用意されています。

SceneManagerで検出できるイベント


シーンの切り替えに関するイベントは以下の3つです。

①シーンのロードが完了した
②シーンのアンロードが完了した
③アクティブシーンが切り替わった

以下、それぞれの使い方を簡単なサンプルで紹介します。

この記事ではUnity2018.1.0を使用しています。
[Unity_317×90]

①シーンのロード完了を検出するイベント


「Scene_A」から「Scene_B」に切り替えるとき、シーンの読み込みが完了したタイミングで SceneManager.sceneLoaded に追加した関数がコールされます。(このスクリプトはScene_Aで動作させます。)

using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneManagerEvent : MonoBehaviour {

	void Start () {
		// イベントにイベントハンドラーを追加
		SceneManager.sceneLoaded += SceneLoaded;
		// シーンの読み込み
		SceneManager.LoadScene("Scene_B");
	}
	
	// イベントハンドラー(イベント発生時に動かしたい処理)
	void SceneLoaded (Scene nextScene, LoadSceneMode mode) {
		Debug.Log(nextScene.name);
		Debug.Log(mode);
	}
}

実行結果

解説
“SceneManager.sceneLoaded”はUnityAPI側で定義されているイベント(eventキーワードで定義される)です。イベントは何らかの状態変化を通知する仕組みであり、この通知に応じて実行される処理はイベントハンドラーと言います。

イベントはデリゲートによって実現されています。デリゲートとは、変数にメソッド(への参照)を格納できる仕組みです。
“SceneLoaded”メソッドはユーザーが命名したメソッドであり、イベントハンドラーとしてイベントに追加しています。
※(イベントへのハンドラーの登録は「+=」「-=」のみ許可されており、「=」はコンパイルエラーとなります。)

イベントハンドラーの定義は、代入したいイベントの定義(SceneManagerクラスにて定義されている)に合わせて行います。したがって、第1引数はScene型、第2引数にLoadSceneMode型の引数を持つように定義します。

”シーンの読み込み完了”というイベントが発生すると、イベントハンドラー(SceneLoadedメソッド)が実行されます。
実行時には、第1引数に遷移後のシーンオブジェクト、第2引数にはシーンの読み込みモード(Single もしくは Additive)が渡されます。この値は上記のサンプルの通りメソッド内で使用できます。

②シーンのアンロード完了を検出するイベント


「Scene_A」から「Scene_B」に切り替えるとき、シーンの破棄が完了したタイミングで SceneManager.sceneUnloaded に追加した関数がコールされます。(このスクリプトはScene_Aで動作させます。)

using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneManagerEvent : MonoBehaviour {

	void Start () {
		SceneManager.sceneUnloaded += SceneUnloaded;
		SceneManager.LoadScene("Scene_B");
	}
	
	void SceneUnloaded (Scene thisScene) {
		Debug.Log(thisScene.name);
	}
}

実行結果

解説
“sceneUnloaded”イベントは”シーンの破棄が完了”というイベントが発生すると、イベントハンドラーが実行されます。
ハンドラーは引数にシーンオブジェクトを持つ必要があり、その引数には、破棄されたシーンオブジェクトが渡されます。

③アクティブなシーンが切り替わったことを検出するイベント


アクティブシーンを「Scene_A」から「Scene_B」に切り替えるとき、以下のスクリプトを動かすと、切り替えが完了したタイミングで SceneManager.activeSceneChanged に追加した関数がコールされます。

例えば下図のようなマルチシーンでは、太字で表示されているの(Scene_A)がアクティブなシーンです。
(マルチシーンにおいては、レンダリングやナビメッシュの設定はアクティブなシーンのものが適用される。)
Unity マルチシーン

using UnityEngine;
using UnityEngine.SceneManagement;

public class SceneManagerEvent : MonoBehaviour {

	void Start () {
		SceneManager.activeSceneChanged += ActiveSceneChanged;

		// アクティブシーンの切り替え
		Scene scene = SceneManager.GetSceneByName("Scene_B");
		SceneManager.SetActiveScene(scene);
	}
	
	void ActiveSceneChanged (Scene thisScene, Scene nextScene) {
		Debug.Log(thisScene.name);
		Debug.Log(nextScene.name);
	}
}

実行結果

/アクティブシーンがScene_Bに切り替わっている\

解説
“activeSceneChanged”イベントは”アクティブシーンの切り替え”というイベントが発生すると、イベントハンドラーが実行されます。ハンドラーは引数2つにシーンオブジェクトを持つ必要があり、それぞれの引数には、切り替え前のたシーンオブジェクトと、切り替え後のシーンオブジェクトが渡されます。
このイベントを通常のシーンロード時に実行すると、上記のスクリプトの”thisScene”はNullを返します。これは新しいシーンがアクティブになったタイミングで、古いシーンのオブジェクトは既に破棄されてしまっているためです。

以上です。

ゲーム制作関連のオススメ連載リンク

とっても手軽なゲーム制作体験!
Unityゲーム開発基礎

実際のリリースゲームを題材にしたハンズオンゲーム制作連載
実践unityゲーム開発

Recent News

Recent Tips

Tag Search