Unityでインディゲームを作る!

Unityでのゲーム制作を目指し、それに関わる話題についてのブログ

Unityエディターでゲームを実行するとヒエラルキーに出てくる謎のDontDestroyOnLoadについて

DontDestroyOnLoad_WhatIsThis?

これは何?

 Unityエディターでプレイヤーを起動すると、ヒエラルキー上に出てくるDontDestroyOnLoadという何か。Don't Destroy(壊すな!)という文言から恐ろしい、触れちゃいけない何かなのかなと思っていたんですが、UnityのScene Management周りを勉強していて、ようやくその正体が分かりました。

 

要約!

DontDestroyOnLoad_SceneHierarchy

DontDestroyOnLoad_MoveToDontDestroy

 先にまとめてしまうと、ヒエラルキー上のDontDestroyOnLoadとはゲームを起動してから終了するまでずっと存在し続けるStaticなSceneであり、ここに存在するゲームオブジェクトは、ランタイム中のシーンのロード、アンロードの影響を受けなくなります。

 DontDestroyOnLoad(Object target)は、目標のゲームオブジェクトをそこに移動させるためのメソッドです。

 

LoadSceneMode

 Unityのシーンをロードする方法は二種類あり、Singleモードは現在のシーンを完全に削除して、新しいシーンを読み込むというものです。もう一つのAdditiveはその名の通り、追加的にシーンを読み込むモードですが、ここでは割愛します。

 

 Singleモードで現在のシーンから新しいシーンにゲームオブジェクトを持ち込むためにDontDestroyOnLoadメソッドを使います。

DontDestroyOnLoadTest_DontDestroyObjectOnNewScene

 ただし、厳密には新たなシーンにゲームオブジェクトが移動するのではなく、DontDestroyOnLoadシーンに移動して、ずっとそこに居続ける、という感じです。

 

重複に注意!

 もしも、そのゲームがリニアな構造で、最初のシーンから最後のシーンまで一方通行の場合、最初のシーンでDontDestroyOnLoad処理をしてしまえば、それ以降はシーンを順に読み込んで進行していく、で問題はないはずです。

 しかし、いくつものシーンを何度も行ったりきたりするようなゲームの場合、最初のシーンを再度読み込むと、またDontDestroyOnLoad処理が実行されてしまい、オブジェクトが重複してしまいます。

 

 公式のドキュメントページではこの対応策として、タグを使って同種のオブジェクトを検索し(FindGameObjectsWithTag)、既に存在してたらDestroyする、という方法を採用しています。今回のテストで書いたスクリプトにも、これを採用しました。

DontDestroyOnLoad_Script

 こういった対応策を取らない限り、該当シーンが読み込まれる度に、DontDestroyOnLoadシーンにゲームオブジェクトが詰みあがっていくので、処理が重複したり、最悪メモリ不足でゲームが落ちる、という事態になるかもしれません。

 

 自分が考えた対応策は、一番初めに初期化のためのシーンを読み込み、そこで必要なオブジェクト、つまりプレイヤーキャラやシステム関連などゲームを通して存在し続けるオブジェクトをDontDestroyOnLoad処理してしまって、その後、直ぐに実際のゲームコンテンツを含むシーンを読み込む、という方法です。

 これだと実質一瞬で、プレイヤーにとって最初のシーンが読み込まれゲームが始まることになり、あとは初期化のためのシーンがロードされなければ、重複の危険性もない、ということになります。この手法は今度試したいと思います。

 

あとがき

 今まさにSceneManagement周りを勉強中なのですが、かなり難しい!しかし、UnityのSceneというものに向き合っていかないとダメな時期だと思うので、なんとか乗り越えたいと思います。