【Unity】シーンの切り替えを検出するイベント
▶
【Unity】3Dアクションゲームを作ろう!#7 ステージの作成(Skybox・落下判定)
▶
【Unity】3Dアクションゲームを作ろう!#8 ステージの作成(スイッチ・扉)
▶
【Unity】3Dアクションゲームを作ろう!#9 プレイヤーのHP管理
▶
【初心者Unity】JsonUtilityクラスでJSONを扱う方法
▶
【初心者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)がアクティブなシーンです。
(マルチシーンにおいては、レンダリングやナビメッシュの設定はアクティブなシーンのものが適用される。)
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】3Dアクションゲームを作ろう!#7 ステージの作成(Skybox・落下判定)
▶
【Unity】3Dアクションゲームを作ろう!#8 ステージの作成(スイッチ・扉)
▶
【Unity】3Dアクションゲームを作ろう!#9 プレイヤーのHP管理
▶
【初心者Unity】JsonUtilityクラスでJSONを扱う方法
▶
【初心者Unity】スクリプトからコンポーネントを追加する方法
ゲーム制作関連のオススメ連載リンク
とっても手軽なゲーム制作体験!
Unityゲーム開発基礎
実際のリリースゲームを題材にしたハンズオンゲーム制作連載
実践unityゲーム開発