渋谷ほととぎす通信

完全趣味でやってるUnityメモ。説明できないところを説明できるようにするための個人ブログ。昨日の自分より少しでも大きくなれるように。。。 ※所属団体とは一切関係がありません

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


f:id:esakun:20150730215258g:plain

環境

  • Unity5.5.2p2

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

無加工GameObjectプレファブの中身を読む

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

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

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

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

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

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

--- !u!」記号を堺にオブジェクトが区切られています。
ピュアGameObject Prefabを、区切り記号を元に整理するとこのようになります。

--- !u!1001 &100100000
Prefab:
# Prefab情報

~~中略~~

--- !u!1 &1618590401530398
GameObject:
# GameObject情報

~~中略~~

--- !u!4 &4882239785013584
Transform:
# Transformコンポーネント情報

~~中略~~

このように以下の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という事になります。


ここまでは1つのPrefab内で完結していた参照関係ですが、ここからは複数の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です。
※fileIDは1つのPrefab内においてユニークなIDです
guidはmetaファイル内に保存されます。
またmetaファイルはAssetsフォルダ配下全てのファイルに対し、同階層で自動的に生成されます。

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

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

guidの確認方法

metaファイルを直接開くのが手っ取り早いです。 調べ方はコチラGUIDの調べ方

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

string guid = UnityEditor.AssetDatabase.AssetPathToGUID(
            UnityEditor.AssetDatabase.GetAssetPath(GetHashCode())
        );

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

まとめ

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

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

あわせてどうぞ

www.shibuya24.info

www.shibuya24.info

www.shibuya24.info

www.shibuya24.info