【Unity】エディター操作でシーン間参照を実現する guid-based-reference
Unityでは複数のシーンを同時に編集することは可能ですが、シーン間の参照は出来ません。今回はソレをGUIDベースでなんとかするアプローチについてです。
シーン間参照(Multi Scene Reference)が出来ない
基本的にUnityのSceneというシステムは、別のシーンへのアクセスは出来ません。そのため、スクリプトを利用して参照先を取得します。例えば
- 現在読込中のシーン全体にFindを実行
- Staticなフィールドに格納
- 特定のオブジェクトに登録し、マッチング
- ユニークなアセットに格納
といった感じです。実際、様々なフレームワークは存在しますが、大抵の場合は上のどれかに行き着くという認識です。
シーン間参照がやりたくなるケース
ここまでして得たい他シーンの情報とは何でしょう。それが○○マネージャーといったオブジェクトを制御するユニークな存在であれば、staticなフィールドに突っ込んでも、まぁ何とかなります。
問題になるのが、シーンから別のシーンにアクセスするようなギミックの場合です。例えばScene1のライトをScene2で制御しようと思うと、これが非常に面倒くさい。
Staticのようにユニークなオブジェクトとして格納する訳にはいきません。
こういった場合に強力な解決策になりそうなのが、Guid Based Referenceです。
GUID BASED REFERENCE
guid-based-referenceはオブジェクトのシーン間参照を実現するために便利なアセットです。Unity Companion Licenseで提供されています。
これは、任意のオブジェクトにGUID(Globally Unique Identifier:ユニークなID)を発行し、GUIDを基点にオブジェクトの参照を行うというアプローチです。インスタンスIDはちょくちょく変わるので、変更しないIDを追加で割り振る事で実現しています。
なんでFileIDじゃ駄目だったんでしょう。
ID管理はコンテンツカタログのように全IDを事前に保存しているタイプではなく、オブジェクトが生成されたタイミングで共有スペースに書き込むタイプです。
つまりロードされていないオブジェクトは参照出来ませんが、参照先と参照元のオブジェクトが揃えば利用可能になります。
なおお察しの通り、この機能は「GUID Manager(シングルトン)に全部の参照を突っ込む」パターンです。
使い方
参照される対象となるGameObjectにGuidComponentを追加します。
これでオブジェクトにユニークなIDが割り振られます。
参照する側のコードを用意します。今回はオブジェクトが接触したらアクティブになる…的なやつです。
同じシーンなら[SerializeField]GameObject target;
と書く所ですが、[SerializeField] GuidReference target;
と記述します。
後はGuid Componentを追加したオブジェクトをドラッグ&ドロップしてやれば、オブジェクトが登録されてアクセス出来るようになります。
また設定時「どのシーンのオブジェクトを参照しているのか」が表示されているので、多少混乱を抑えられます。
なお、取得できるのはGameObjectだけです。ジェネリックも使えないので、対象がその点に注意です。
また内部的にGameObjectをキャッシュしてくれてるのでGUIDで毎回検索する訳ではありませんが、取れるのがGameObjectのため必然的にGetComponent連打することになります。毎フレーム動かすような物はキャッシュしておくと色々と良いです。
Guid Based Referenceの使い方。ゲーム唯一のオブジェクトとかなら兎も角、ステージ上のギミック同士の参照とかはエディターでやりたい派 pic.twitter.com/g6UKmS3NLv
— 椿 (@tsubaki_t1) September 6, 2018
関連
この機能を作るに当たって得られた幾つかのTipsが紹介されています。
blogs.unity3d.com似たような違う機能
tsubakit1.hateblo.jp共有するのがスコアの場合
tsubakit1.hateblo.jpオブジェクトへ直接参照するんじゃなくて、一旦ScriptableObjectを通せば…というアプローチ。