いろいろガンガンいこうぜ。体も大事に

普段はJavaでAndroidアプリ開発しているプログラマーのブログです。

Unityのシーンファイルの中身を見てみた (2)

Unityのシーンファイルの中身を見てみた(1)の続きです。


Unity 4.2から,無料版でもテキストベースでシーン・マテリアルなどを保存出来るようになり,バージョン管理システムなどで差分を確認しやすくなりました。Unityのシーンを編集した際に,シーンはテキストベースでその表現がどのように変化するかを確認してみました。



シーン中に空のゲームオブジェクトを置いた時,.unityファイルには,以下のようなテキストが追加されました。

--- !u!1 &1696434231
GameObject:
  m_ObjectHideFlags: 0
  m_PrefabParentObject: {fileID: 0}
  m_PrefabInternal: {fileID: 0}
  serializedVersion: 4
  m_Component:
  - 4: {fileID: 1696434232}
  m_Layer: 0
  m_Name: EmptyGameObject
  m_TagString: Untagged
  m_Icon: {fileID: 0}
  m_NavMeshLayer: 0
  m_StaticEditorFlags: 0
  m_IsActive: 1
--- !u!4 &1696434232
Transform:
  m_ObjectHideFlags: 0
  m_PrefabParentObject: {fileID: 0}
  m_PrefabInternal: {fileID: 0}
  m_GameObject: {fileID: 1696434231}
 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
  m_LocalPosition: {x: 0, y: 0, z: 0}
  m_LocalScale: {x: 1, y: 1, z: 1}
  m_Children: []
  m_Father: {fileID: 0}+--- !u!1 &1696434231
GameObject:
  m_ObjectHideFlags: 0
  m_PrefabParentObject: {fileID: 0}
  m_PrefabInternal: {fileID: 0}
  serializedVersion: 4
  m_Component:
  - 4: {fileID: 1696434232}
  m_Layer: 0
  m_Name: MyGameObject
  m_TagString: Untagged
  m_Icon: {fileID: 0}
  m_NavMeshLayer: 0
  m_StaticEditorFlags: 0
  m_IsActive: 1
--- !u!4 &1696434232
Transform:
  m_ObjectHideFlags: 0
  m_PrefabParentObject: {fileID: 0}
  m_PrefabInternal: {fileID: 0}
  m_GameObject: {fileID: 1696434231}
  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
  m_LocalPosition: {x: 0, y: 0, z: 0}
  m_LocalScale: {x: 1, y: 1, z: 1}
  m_Children: []
  m_Father: {fileID: 0}


さて,前回のおさらいになりますが,

--- !u!1 &1696434231

これは,!u!1でこのYAMLドキュメントがGameObject型の情報を表し,&の後でこのidが1696434231であることを表しているようです。

--- !u!4 &1696434232

同様に,!u!4でこのYAMLドキュメントがTransform型の情報を表し,&の後でこのidが1696434232であることを表しているようです。
(型と!u!の後のクラスidの対応はこちら。)




ではこのGameObject(以後,MyGameObject)のデフォルト状態のTransformを

  • Positionはx = 2, y = 3, z = 4
  • Rotationはx = 30, y = 10, z = 20
  • Scaleはx = 0.5, y = 0.1, z = 1.5

のように変更しました。

gitで差分を確認すると以下のようになりました。

-  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
-  m_LocalPosition: {x: 0, y: 0, z: 0}
-  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_LocalRotation: {x: .268535882, y: .0381345674, z: .144878149, w: .951548576}
+  m_LocalPosition: {x: 2, y: 3, z: 4}
+  m_LocalScale: {x: .5, y: .100000001, z: 1.5}

Position,Rotation,Scaleそれぞれの要素がYAMLのフロー形式で表現されているようです。

RotationはEditor上では,x,y,zの3つの入力項目あります。TransformクラスのlocalRotationはQuertanion型で定義されています。YAMLではm_LocatlRotationがクォータニオン型として定義されているためからか,x,y,z,wの4つの項目で表現されています。
設定されているコンポーネントの値を変えるくらいだったら,差分は非常に確認しやすいですね。



次にMyGameObjectにRigidbodyコンポーネントを付与してみましす。

以下のようなRigidbodyコンポーネントの情報・設定を表現する部分が.unityファイルに追加されました。54はRigidbodyクラスのクラスidです。

+--- !u!54 &1696434233
+Rigidbody:
+  m_ObjectHideFlags: 0
+  m_PrefabParentObject: {fileID: 0}
+  m_PrefabInternal: {fileID: 0}
+  m_GameObject: {fileID: 1696434231}
+  serializedVersion: 2
+  m_Mass: 1
+  m_Drag: 0
+  m_AngularDrag: .0500000007
+  m_UseGravity: 1
+  m_IsKinematic: 0
+  m_Interpolate: 0
+  m_Constraints: 0
+  m_CollisionDetection: 0

これに加えて,MyGameObjectのYAMLドキュメント中に以下のような追加がありました。

   (略)
   serializedVersion: 4
   m_Component:
   - 4: {fileID: 1696434232}
+  - 54: {fileID: 1696434233}
   m_Layer: 0
   m_Name: EmptyGameObject
   (略)

m_Componentは,配列になっているようです。
その配列の要素はマップになっていて,キーがコンポーネントのクラスidで,バリューがさらにマップになっているようです。
そのマップは,fileIDという文字列をキーに持ち,YAMLドキュメントのidをバリューに持つようです。

MyGameObjectはTransform型(id : 4)とRigidbody型( id : 54)が付与されていて,それぞれのコンポーネントの値・情報はidが1696434232,1696434233のYAMLドキュメントにあるということが表現されているようです。

実際に,さきほどidが1696434233のRigidbodyの情報を表現するYAMLドキュメントが追加されています。




次に,空のゲームオブジェクトをMyGameObjectに子オブジェクトとして追加します。

+--- !u!1 &141034563
+GameObject:
  (略)
+--- !u!4 &141034564
+Transform:
  (略)
+  m_Father: {fileID: 1696434232}

.unityファイルに空のゲームオブジェクトとそのTransformを表すYAMLドキュメントが追記されました。

また,MyGameObjectに

--- !u!1 &1696434231
GameObject:
  (略)
   m_LocalScale: {x: .5, y: .600000024, z: 1.5}
-  m_Children: []
+  m_Children:
+  - {fileID: 141034564}
   m_Father: {fileID: 0}

以下のような追記がされました。

MyGameObjectのTransformのYAMLドキュメントのidは1696434232。新たに追記した空のゲームオブジェクトのTransformのYAMLドキュメントのidは141034564です。
MyGameObjectのm_Childrenでは,新たに追加した空のゲームオブジェクトのTransfromを参照しています。
新たに追加した空のゲームオブジェクトのm_Fatherでは,MyObjectのTransfromを参照しています。

親子関係は,Transformで関係を作っていることが.unityでもわかります。




コンポーネントのプロパティの値の変更,ゲームオブジェクトへのコンポーネントの追加,子オブジェクトの追加でどのように差分があるのかを確認してみました。
コンポーネントのプロパティの値の変更くらいだったら,差分は追いやすいのですが,ゲームオブジェクトを新規追加すると,一つにつきGameObjectとTransformのYAMLドキュメントが必ず作成されるので差分が非常に多くなりますね。




次は,自作コンポーネントでの差分とプレハブなどの差分を確認したいと思います。


それではまた会えることを祈りつつ