テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】エディター操作でシーン間参照を実現する guid-based-reference

Unityでは複数のシーンを同時に編集することは可能ですが、シーン間の参照は出来ません。今回はソレをGUIDベースでなんとかするアプローチについてです。

シーン間参照(Multi Scene Reference)が出来ない

基本的にUnityのSceneというシステムは、別のシーンへのアクセスは出来ません。そのため、スクリプトを利用して参照先を取得します。例えば

  • 現在読込中のシーン全体にFindを実行
  • Staticなフィールドに格納
  • 特定のオブジェクトに登録し、マッチング
  • ユニークなアセットに格納

といった感じです。実際、様々なフレームワークは存在しますが、大抵の場合は上のどれかに行き着くという認識です。

 

シーン間参照がやりたくなるケース

ここまでして得たい他シーンの情報とは何でしょう。それが○○マネージャーといったオブジェクトを制御するユニークな存在であれば、staticなフィールドに突っ込んでも、まぁ何とかなります。

問題になるのが、シーンから別のシーンにアクセスするようなギミックの場合です。例えばScene1のライトをScene2で制御しようと思うと、これが非常に面倒くさい。
Staticのようにユニークなオブジェクトとして格納する訳にはいきません。

f:id:tsubaki_t1:20180904010641j:plain

こういった場合に強力な解決策になりそうなのが、Guid Based Referenceです。

 

GUID BASED REFERENCE

guid-based-referenceはオブジェクトのシーン間参照を実現するために便利なアセットです。Unity Companion Licenseで提供されています。

github.com

これは、任意のオブジェクトにGUID(Globally Unique Identifier:ユニークなID)を発行し、GUIDを基点にオブジェクトの参照を行うというアプローチです。インスタンスIDはちょくちょく変わるので、変更しないIDを追加で割り振る事で実現しています。
なんでFileIDじゃ駄目だったんでしょう。

ID管理はコンテンツカタログのように全IDを事前に保存しているタイプではなく、オブジェクトが生成されたタイミングで共有スペースに書き込むタイプです。
つまりロードされていないオブジェクトは参照出来ませんが、参照先と参照元のオブジェクトが揃えば利用可能になります。

f:id:tsubaki_t1:20180904013958g:plain

なおお察しの通り、この機能は「GUID Manager(シングルトン)に全部の参照を突っ込む」パターンです。

 

使い方

参照される対象となるGameObjectにGuidComponentを追加します。
これでオブジェクトにユニークなIDが割り振られます。

f:id:tsubaki_t1:20180904014448j:plain

参照する側のコードを用意します。今回はオブジェクトが接触したらアクティブになる…的なやつです。
同じシーンなら[SerializeField]GameObject target;と書く所ですが、[SerializeField] GuidReference target;と記述します。

gist.github.com

後はGuid Componentを追加したオブジェクトをドラッグ&ドロップしてやれば、オブジェクトが登録されてアクセス出来るようになります。
また設定時「どのシーンのオブジェクトを参照しているのか」が表示されているので、多少混乱を抑えられます。

f:id:tsubaki_t1:20180904015224g:plain

なお、取得できるのはGameObjectだけです。ジェネリックも使えないので、対象がその点に注意です。
また内部的にGameObjectをキャッシュしてくれてるのでGUIDで毎回検索する訳ではありませんが、取れるのがGameObjectのため必然的にGetComponent連打することになります。毎フレーム動かすような物はキャッシュしておくと色々と良いです。

 

 

関連

この機能を作るに当たって得られた幾つかのTipsが紹介されています。

blogs.unity3d.com似たような違う機能

tsubakit1.hateblo.jp共有するのがスコアの場合

tsubakit1.hateblo.jpオブジェクトへ直接参照するんじゃなくて、一旦ScriptableObjectを通せば…というアプローチ。

tsubakit1.hateblo.jp

baba-s.hatenablog.com