この記事でのバージョン
Unity 5.6.0f3
はじめに
Unityではシーン遷移時にシーン上のGameObjectは全て破棄されてしまいます。
なので、破棄したくない物にはDontDestroyOnLoadを実行して、永遠に破棄されないようにします。
DontDestroyOnLoad(gameObject);
ただ、このやり方だとDontDestroyOnLoadしたオブジェクトは自動では永遠に破棄されないので、
特定のシーンでだけ破棄されないようにするにはひと工夫必要です。
という事で今回は、特定のシーンでだけ破棄されないオブジェクトの実装方法をご紹介!
イメージとしては以下のような感じ。
Hieararchyを見るとシーンを移動する度に
不要なGameObjectが破棄されているのが分かるかと思います。
DontDestroyObjectManager
早速ですが、特定のシーンでだけ破棄されないオブジェクトを管理するクラス
DontDestroyObjectManagerのプログラムです。
なお、DontDestroyObjectManagerを使うには
必要になります。これらについて詳しく知りたい方は以下の記事をどうぞ。
上記4つのスクリプトを作成し、適当なGameObjectに
SceneNavigatorとDontDestroyObjectManagerをそれぞれアタッチすると設定完了です。
ここで注意が必要なのが、DontDestroyObjectManagerは複数配置するとエラーが出る事です。
最初のシーンにだけ配置する、または作成するプログラムを一度だけ実行するようにしましょう。
もしくは以下の方法を併用すると良いかもしれません。
使い方
使い方は、特定のシーンでだけ破棄したくないオブジェクトを
DontDestroyObjectManagerのSetメソッドを使って設定するだけ。
Setは以下のようにSet(オブジェクト, シーン名1, シーン名2, …)という形式で実行します。
シーン名は単体で複数でもいいですし、Listや配列で設定する事も可能です。
//Title以外に行ったらgameObjectを破棄するように設定 DontDestroyObjectManager.Instance.Set(gameObject, "Title"); //GameかResult以外に行ったらgameObjectを破棄するように設定 DontDestroyObjectManager.Instance.Set(gameObject, "Game", "Result"); //TitleかResult以外に行ったらgameObjectを破棄するように設定 List<string> sceneNameList = new List<string>(){"Title", "Result"}; DontDestroyObjectManager.Instance.Set(gameObject, sceneNameList); //TitleかGameかResult以外に行ったらgameObjectを破棄するように設定 string[] sceneNameArray = new string[]{"Title", "Game", "Result"}; DontDestroyObjectManager.Instance.Set(gameObject, sceneNameArray);
これで最初のイメージのような実装が出来るようになります。
なお、分かりやすいように有効なシーン名をオブジェクト名にしています。
上記のイメージを見て分かる通り、DontDestroyObjectManagerに
設定したオブジェクトはDontDestroyObjectManagerの子になるので注意が必要です。
実装方法
実装方法は、SceneNavigatorを使ってシーン移動前を検知し、
その時に不要なオブジェクトを破棄するようにしているだけだったりします。
SceneManagerのsceneLoadedを使えば似たような実装は可能なのですが、
sceneLoadedはシーンが読み込まれた後に実行されるので、SceneNavigatorを使いました。
おわりに
今回の方法を使えば、同じシーンを繰り返す時や複数シーンで共通のオブジェクトがある場合に
何度も作り直さずに済むようになります。
なお、シーン名は定数にした方が何かと便利だと思います。