ひとりでのアプリ開発 - fineの備忘録 -

ひとりでアプリ開発をするなかで起こったことや学んだことを書き溜めていきます

Unity - SceneManager.Events:シーンの切り替えを検出する -

初めに

 Scene の切り替えを検出するイベント(sceneLoaded、sceneUnloaded、activeSceneChanged)についてまとめます。

SceneManager

 SceneManager は実行時のシーンの管理をする UnityEngine.SceneManagement のクラスになります。

 使用するには、名前空間に下のように記述する必要があります。

using UnityEngine.SceneManagement;

docs.unity3d.com

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

イベント 説明
sceneLoaded シーンのロード完了を検出
sceneUnloaded シーンがアンロードを検出
activeSceneChanged アクティブなシーンが切り替わったことを検出

sceneLoaded:シーンのロード完了を検出

 シーンの読み込みが完了したタイミングで SceneManager.sceneLoaded に追加した関数がコールされます。

using UnityEngine;
using UnityEngine.SceneManagement;  //追加

public class ExampleCode : MonoBehaviour
{
    void Start()
    {
        SceneManager.sceneLoaded += OnSceneLoaded;  //sceneLoadedに関数を追加
    }

    //関数の定義
    void OnSceneLoaded( Scene scene, LoadSceneMode mode )
    {
        Debug.Log ( scene.name + " scene loaded");
    }
}

 上のスクリプトでは、SceneManager.sceneLoaded に OnSceneLoaded という関数を追加しています。追加する関数は自分で命名し、第1引数は Scene、第2引数は LoadSceneMode になるように定義します。

 LoadSceneMode はシーンのロードの時に使われます。下の2つからロードの仕方を選べます。

変数 説明
Single 現在ロードされているシーンを破棄し、次のシーンをロードする
Additive 現在ロードされているシーンに、次のシーンを追加してロードする

 Single は通常のシーンのロードと考えてよいでしょう。
 Additive では複数のシーンが同時にロードされている状態になります。 Multi Scene Editing という複数のシーンを同時に編集する場合に使われるものです。公式のドキュメントのリンクを載せておきます。Multi Scene Editing についてはそちらをご覧ください。

docs.unity3d.com
docs.unity3d.com

sceneUnloaded:シーンがアンロードを検出

 シーンの破棄が完了したタイミングで SceneManager.sceneUnloaded に追加した関数がコールされます。

using UnityEngine;
using UnityEngine.SceneManagement;  //追加

public class ExampleCode : MonoBehaviour
{
    void Start()
    {
        SceneManager.sceneUnloaded += OnSceneUnloaded;  //sceneUnloadedに関数を追加
    }

    //関数の定義
    void OnSceneUnloaded(Scene current)
    {
        Debug.Log("OnSceneUnloaded: " + current);
    }
}

 使い方は sceneLoaded とほぼ同じになります。SceneManager.sceneUnloaded に関数を追加し、シーンの破棄が完了したタイミングで追加した関数を呼び出します。
 sceneLoaded との違いは、定義する関数の引数になります。シーンのアンロードを検出するだけなので、ロードに使われる LoadSceneMode は必要ありません。
 

activeSceneChanged:アクティブなシーンが切り替わったことを検出

 アクティブなシーンを切り替えるとき、切り替えが完了したタイミングで SceneManager.activeSceneChanged に追加した関数がコールされます。

using UnityEngine;
using UnityEngine.SceneManagement;
 
public class ExampleCode : MonoBehaviour {
 
    void Start () {
        SceneManager.activeSceneChanged += ChangedActiveScene;
 
        // アクティブシーンの切り替え
        Scene scene = SceneManager.GetSceneByName("SceneB");
        SceneManager.SetActiveScene(scene);
    }
     
    void ChangedActiveScene (Scene thisScene, Scene nextScene) {
        Debug.Log(thisScene.name);
        Debug.Log(nextScene.name);
    }
}

 activeSceneChanged は Multi Scene Editing という複数のシーンを同時に編集する場合に使われるものです。

 複数のシーンを同時編集可能にするには、Hierarchy にシーンをドラッグ&ドロップすればよいです。アクティブなシーンが太字になっています。

 上のスクリプトをゲームオブジェクトにつけて、実行するとアクティブなシーンが SceneA から SceneB に変わっていることが分かります。

 通常のシーンロード時に使うと前のシーンは破棄されているため、thisScene は null を返します。
 下のスクリプトのように SceneManager.LoadScene を使うと null が返ってくることがわかります。

using UnityEngine;
using UnityEngine.SceneManagement;
 
public class ExampleCode : MonoBehaviour {
 
    void Start () {
        SceneManager.activeSceneChanged += ChangedActiveScene;
 
        // シーンのロード
        SceneManager.LoadScene("SceneB");
    }
     
    void ChangedActiveScene (Scene thisScene, Scene nextScene) {
        Debug.Log(thisScene.name);
        Debug.Log(nextScene.name);
    }
}


最後に

 シーンの切り替えを検出する方法をまとめました。activeSceneChanged は複数シーンの同時編集をする場合以外では使わなくてよいでしょう。 他の二つはよく使うので覚えておきたいです。