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で動作させます。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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で動作させます。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 マルチシーン

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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