今回はマルチシーンエディティングについてです。
マルチシーンエディティング
マルチシーンエディティング(Multi Scene Editing)はUnity 5.3から入った機能で、複数のシーンを同時の編集する機能です。
複数のシーンを同時に編集できる、それだけではありますが、その機能を応用すると色々な用途に使えそうです。例えば
- 「ステージ」や「ギミック」毎にシーンに分割して、お互いに管理する
- 広大なステージを複数のシーンに分割して、必要になったら読む
- UIをシーン毎に管理する
- テストシーンで作成した機能を本番シーンに移植する
ステージやギミック毎にシーンを分割して同時編集
マルチシーンエディティングで真っ先に思いつく「ステージ」や「プレイヤー」で分割するアプローチです。
ステージとギミックを別シーンとして作成し、実行時に合体するようなイメージで作ります。
ステージを触る人やレベルデザインしたい人、システムを作りこむ人が各々のシーンで進行出来るので、割とスマートに進めます。
難易度調整のように、ステージは同一だけど敵の位置や強さが異なる…そんなケースでもこのアプローチは有効に使えそうです。
ステージを複数のシーンに分割して編集・平行構築
広大なステージを表示する場合、単一のシーンではなく複数のシーンに分割することで、ゲームがプレイできるようになるまでの時間削減や、メモリの負荷、ステージの調整といった部分において有利です。
ステージをマルチシーンエディティングで分割する場合、NavmeshやLightmap・OcclusionCullingといったシーンに紐づく情報はActiveなシーンに対して行われるみたいです。
作ったライトマップやNavmeshは、アクティブなシーンに作られ、他のシーンを読んだ際にもそこからロードされるっぽいです。
ちなみにUnity 5.3.1現在、他のシーンのオブジェクトを参照していると、参照元にオブジェクトのコピーが作られます(Cross-scene references)。
何が問題かと言えば、OcclusionCullingを使用すると全てのシーンが持つステージがアクティブなオブジェクトに作られます。なので、現状Occlusion Cullingはこの手法では使えないっぽいです。
修正されたっぽいです。
現在、シーン間参照は出来ません。
(可能にするAPIもありますが、コピーが作成されます)
シーン毎にUIを作成して加算読込とか管理
UI毎にシーンを管理します。
単一のプレハブをインスタンス化するアプローチと異なり、「プレハブをテンプレートとして使う」機能を手軽に使うことが出来ます。
上に書いた通りUnity 5.3.1現在、他のシーンのオブジェクトを参照していると、参照元にオブジェクトのコピーが作られます(Cross-scene references)
このため、オブジェクト間の参照はマネージャー用シーンを用意して、そこに参照をまとめるのが良さそうです。
また参照するのはマネージャーからではなく、各シーンからマネージャーに対して行うのをお勧めします。これは「幾つかのシーンが足りなくても動作する」ことで動作確認を単純化することと、シーン自体がResourcesのPrefabと違って1F待つ必要がある為です。
使わなくなったシーン(≒UI)は、どんどんUnloadしてしまいます。
詳しい実装方法はまた今度。
本番シーンに機能を移植
複数のシーンを同時に編集できるので、テスト用シーンから本番シーンへ機能を移植する際に、「テスト用シーンでオブジェクトコピペして、本番シーンを開いてペースト…をオブジェクトの数だけ繰り返す」みたいなことをしなくても良くなります。
コンポーネントのパラメータの移植は、Copy ComponentやPaste Componentでコンポーネントのコピー&ペーストなんかで行います。
Cross-scene referencesの問題でテスト用のシーンを参照してる機能があったら勝手にオブジェクトが作られてしまうので、その辺り注意です。
また、シーンファイルをシーンへD&Dするとシーンのマージが出来たりします。これはマルチシーンエディティングというよりは、UnityYamlMeargeの力です。
マルチシーンエディティングの使い方
マルチシーンエディティングの使い方についてです。
最初は複数のシーンを同時編集可能にします。やり方は簡単、シーンファイルをHierarchyへドラッグ&ドロップするだけです。
シーンが追加されると、オブジェクトの親階層がシーン…のような感じになります。
エディタでシーンを追加・破棄
ロードしたシーンを外したい場合、二通りの考え方があります。
一つはUnload Scene、もう一つはRemove Sceneです。
Unload Sceneの場合、シーンは閉じられ一時的に使用できなくなります。閉じたシーンは、Load Sceneで再度開くことが出来ます。
Remove Sceneは、Hierarchyからシーンを削除します。この操作を行うと、Hierarchyからシーンが破棄され、追加する前の状態に戻ります。
ちなみに、アクティブなシーン(最初に開いたシーン)は閉じることが出来ないみたいです。一応SetAcrive Sceneで切り替えが出来るみたいなので、必要に応じて。
実行時にスクリプトでシーンを追加・破棄
ゲームプレイ中にシーンを追加・破棄する場合は、SceneManagerを使用します。
// 追加ロード
UnityEngine.SceneManagement.SceneManager.LoadScene ("シーン名", LoadSceneMode.Additive);
// シーンの切り替え
UnityEngine.SceneManagement.SceneManager.LoadScene ("シーン名", LoadSceneMode.Single);
基本的な挙動はApplication.LoadLevelやApplication.LoadlevelAditiveと同じです。
シーンはUnloadSceneで破棄します。
UnityEngine.SceneManagement.SceneManager.UnloadScene ("シーン名");
シーンが既に読まれている場合はロードしない…といった処理を行いたい場合は、こんな感じです。
if (SceneManager.GetSceneByName ("Common").isLoaded == false) {
UnityEngine.SceneManagement.SceneManager.LoadScene ("Common", LoadSceneMode.Additive);
}
関連
neue cc - Unity 5.3のMulti Scene EditingをUniRxによるシーンナビゲーションで統合する