渋谷ほととぎす通信

完全趣味でやってる技術メモ。※所属団体とは一切関係がありません。

Unity Prefabの中身(YAML)を読んで参照関係を正しく理解する


f:id:esakun:20150730215258g:plain:w450

環境

  • Unity5.5.2p2

先日Prefabファイルのテキストの中身を読む機会がありました。
じっくりと読んでみて自分自身理解が出来ていない部分があったので、調べながらまとめてみます。

無加工GameObjectのprefabの中身を読む

prefabの中身を読むまでの手順

  1. ヒエラルキーでGameObjectを作成
  2. コンポーネントを付けるなど、何も手を加えずプレファブ化する(以下 : ピュアGameObjectと呼称する)
  3. ピュアGameObject Prefabをテキストエディタで開く

PrefabはYAML形式で記述されています。
※公式ページの説明はコチラです。

すると41行のYAMLが現れます。

パッと見何のこっちゃですが1つずつ読み解いていきます。

オブジェクトごとの区切り

この41行のYAMLには3つのオブジェクト情報が格納されています。

--- !u!」記号を堺に内容が区切られていることが分かります。 ピュアGameObject Prefabを、区切り記号を元に整理するとこのようになります。

このように以下の3つの情報が格納されています。

  • Prefab情報
  • GameObject情報
  • Transformコンポーネント情報

fileIDを使ってオブジェクト同士の参照関係を作る

オブジェクト同士の参照関係はfileIDを使って保持しています。fileIDは、Unityエディタのインスペクタ上では、以下の画像のようにLocal Identifier In Fileの事です。

f:id:esakun:20170324191034p:plain
インスペクタ上におけるTransformコンポーネントのLocal Identifier In File
※通常インスペクタではLocal Identifier In Fileは閲覧できませんが、画像右上のようにDebugモードに切り替えると確認出来るようになります。

f:id:esakun:20170324193147p:plain
Prefab側のTransformコンポーネントのfileID

インスペクタ、Prefab内の数値が共に一致していることが分かります。
TransformコンポーネントのfileID(Local Identifier In File)は、4882239785013584ということです。

ところでfileIDとは何か?

Prefab内におけるユニークIDです。あくまで1つのPrefab内における話なので、他のPrefab内ではその数値が使われている可能性はあります。

fileIDはあくまでローカルなIDということです。

オブジェクト参照方法

Prefab内のGameObject情報を見てみます。

f:id:esakun:20170324202006p:plain

このようにTransformコンポーネントのfileIDが使用されています。

m_Component:
- component: {fileID: 4882239785013584}

20~21行目はこのGameObjectにAddComponentされているコンポーネント定義です。ピュアGameObjectにはTransformコンポーネントしか無いという事がこの記述から読み取れます。

ここまでのまとめ

このようにオブジェクトの参照はfileIDを使います。当然ですが、この値をUnity外で変えてしまうと参照が外れてしまい、Missing Componentという事になります。

複数Prefabの参照関係

ここまでは1つのPrefab内で完結していた参照関係ですが、ここからは複数のPrefabの参照関係ではどのように記述が変化するかを見ていきます。

GameObject1、GameObject2というピュアGameObjectのPrefabを2つ作り、GameObject1の方にコチラの以下のソースのReferenceコンポーネントをくっつけます。

また、Referenceコンポーネントのgo変数にGameObject2の参照を渡します。


f:id:esakun:20170324203907p:plain
インスペクタ上ではこのようになります。

ではGameObject1.prefabの中身を確認してみます。

44〜54行目にMonoBehaviour情報が追加されているのが分かります。

この部分がReferenceコンポーネントがAddComponentされているという状態です。
その証拠として、MonoBehaviourのfileID 114590338507709626 が登録コンポーネントとしてGameObject情報に追加されています。

m_Component:
  - component: {fileID: 4882239785013584}
  - component: {fileID: 114590338507709626}

外部オブジェクトの参照記述

またMonoBehavioiur情報には、新たな記述があります。

m_Script: {fileID: 11500000, guid: 10bfbdf26587d443f80b07b141050b5a, type: 3}
~~中略~~
go: {fileID: 1618590401530398, guid: d2720dae1a09243a98719884320a6710, type: 2}

今までfileIDだけで参照関係を保持していましたが、複数のPrefabをまたがるとguidという新たなIDが現れます。

guidとは、プロジェクト全体通してユニークなIDでmetaファイル内に保存されます。
※fileIDは1つのPrefab内においてユニークなIDです

ご存知の通り、metaファイルはAssetsフォルダ配下全てのファイルに対し、同階層で自動的に生成されます。それぞれがユニークなIDが振られたファイルだということになります。

go: {fileID: 1618590401530398, guid: d2720dae1a09243a98719884320a6710, type: 2}

例えばこの記述は、guidに紐づくオブジェクトがgo変数にアタッチされているということを指します。
guid記述があるためPrefab外ファイルの参照であるということが分かります。

guidの確認方法

metaファイルを直接開くのが手っ取り早いです。調べ方はこちらの記事にまとめていますのでご参考にどうぞ。

ちなみにUnityエディタ上で確認することは、デフォルト状態では出来ません。
※Debugモードでも確認することは出来ません

このようなUnityEditorスクリプトを書いてエディタ拡張をして表示させることは可能です。

まとめ

私は今までファイル参照はguidだけで管理していると勘違いしていたようです。
外部ファイルの参照はguidで、その中のオブジェクト参照はfileIDで行っています。

たまにはPrefabの中身を読んでみるのも良いものです。

あわせてどうぞ