Unityでシーンを切り替えると、原則として元のシーンにあったゲームオブジェクトが遷移先のシーンに引き継がれることはありません。
しかしゲームを作っているとシーンをまたいで存在するゲームオブジェクトを作りたくなる時がありますよね。今回はそのようなゲームオブジェクトの作り方について説明します。
「DontDestroyOnLoad関数」を使ってシーンをまたいでも破棄されないゲームオブジェクトを作る方法
まず、シーンをまたいでも破棄されないゲームオブジェクトの作り方はとても簡単です。C#スクリプトでDontDestroyOnLoad関数を使い、破棄したくないオブジェクトを指定するだけです。
DontDestroyOnLoad(シーン遷移時に破棄したくないゲームオブジェクト)
例えば下のC#スクリプトをゲームオブジェクトにアタッチすると、そのゲームオブジェクトはシーンをまたいでも破棄されなくなります。
using UnityEngine; public class TestScript : MonoBehaviour { void Start() { DontDestroyOnLoad(gameObject); } }
これは例えば、
- ゲーム進行を管理するためのゲームオブジェクト
- BGMを鳴らすためのゲームオブジェクト
などに使うと便利です。
ゲームオブジェクトが重複しないようにする「シングルトン」の概念
ただし単純に上記の方法を使う場合、「シーンに1つだけあればいいオブジェクト」がシーンの切り替えによって重複して存在してしまう場合があることに注意する必要があります。
例えばの話、プレイヤーキャラが各シーンに1人ずつ配置されていた場合にプレイヤーキャラを破棄しないオブジェクトに指定すると、シーンを移動したときにプレイヤーキャラが2人以上存在することになってしまいます。しかしだからといって各シーンからプレイヤーキャラを消してしまうと、テストプレイの時にいちいち最初からプレイしなければならなくなってしまいます。これでは困りますよね。
そこでゲーム開発では「シングルトン」という概念が導入されることがあります(※これはUnityの機能ではなく、便利な考え方なので注意してください)。シングルトンとは「シーンに必ず1つだけ存在することを保証するゲームオブジェクト」のことです。
シングルトンの考え方としては、あるゲームオブジェクトをシーンに必ず1つだけ存在させたいなら
- 遷移先のシーンに配置されているゲームオブジェクトに、遷移元のシーンから持ってきた同じゲームオブジェクトがあるどうかをチェックさせる。
- もし遷移元のゲームオブジェクトが存在するなら、遷移先のゲームオブジェクト自身を削除する
という感じになります。
シングルトンの実装方法
さてシングルトンの実装方法は色々あると思うのですが、個人的には次のようなやり方を使っています。
using UnityEngine; public class SingletonSample : MonoBehaviour { public static SingletonSample instance; void Awake() { CheckInstance(); } void CheckInstance() { if(instance == null) { instance = this; } else { Destroy(gameObject); } } }
- 最初にこのスクリプトが動作するときはinstance変数がnullなので、CheckInstance関数によりinstance変数にこのスクリプト自身への参照が格納されます。
- 二回目以降にこのスクリプトが起動するときは、intstance変数はnullではないため新しい方のゲームオブジェクトが削除され、最初からあるゲームオブジェクトだけが残ります。
おまけ:シーン間でデータを共有する場合はScriptableObjectを使う方法もある
最後に余談なのですが、シーン間で何らかのデータを共有する場合は「DontDestroyOnLoad+シングルトン」のやり方のほかにScriptableObjectを使う方法もあることは覚えておいて損はないと思います。
ScriptableObjectにはどのシーンからでも参照できる性質があるので、シーン間で共有したい一時的なデータを格納するときに便利です。個人的にはこちらの方法のほうが好きなのでよく使っています。
なおScriptableObjectについては下記で詳しく説明していますので、併せてご覧頂ければと思います。
おわりに
以上、簡単ではありますが
- シーンをまたいで存在するゲームオブジェクトの作り方
- シングルトンの実装方法
についてご説明しました。どちらも簡単にできるのでぜひ試してみてください。
この記事がUnityでのゲーム開発のお役に立てば幸いです。