シーンファイルの正体【Unity】
Unityを使っているとき、ほぼ確実に使う「シーンファイル」。
拡張子は.unityで、シーンを保存すると作成されます。
けどこれ何を保存してるんだろう・・・
シーンの情報が入っているんだろうけど・・・
・・・
気になったので調べました!
今回使用したUnityのバージョンはUnity2018 3.7f1です。
SampleScene.unityはこんなかんじ
%YAML 1.1 %TAG !u! tag:unity3d.com,2011: --- !u!29 &1 OcclusionCullingSettings: m_ObjectHideFlags: 0 serializedVersion: 2 m_OcclusionBakeSettings: smallestOccluder: 5 smallestHole: 0.25 backfaceThreshold: 100 m_SceneGUID: 00000000000000000000000000000000 m_OcclusionCullingData: {fileID: 0} --- !u!104 &2 RenderSettings: ・・・ [中略] ・・・ --- !u!4 &534669905 Transform: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 534669902} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 1, z: -10} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
結構長い(266行)
ぱっと見たところ、RenderSettingsやGameObject、Transformといった単語が見られます。
それに階層分けされている雰囲気です。
ゲームオブジェクトを新たに作成するとどうなるのか
以下の部分が追加されました。
--- !u!1 &1828928079 GameObject: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} serializedVersion: 6 m_Component: - component: {fileID: 1828928080} m_Layer: 0 m_Name: GameObject m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 --- !u!4 &1828928080 Transform: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1828928079} 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} m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
これを見ると、
--- !u!1 &1828928079
の部分が始まりで、その下に、
GameObject: Transform:
といったようなコンポーネントの情報が続いています。
Transformを変更してみた
--- !u!1 &1828928079 GameObject: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} serializedVersion: 6 m_Component: - component: {fileID: 1828928080} m_Layer: 0 m_Name: GameObject m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 --- !u!4 &1828928080 Transform: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1828928079} m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 1, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_Children: [] m_Father: {fileID: 0} m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
Transform:以下のm_LocalPosition:の部分が{x: 1, y: 0, z: 0}に変わっています!
では、シーンファイルのデータを直接変えたらどうなるでしょうか?
Transform:以下のm_LocalScale:を{x: 2, y: 1, z: 1}に変えてみます!
外部変更が検知され、
Unity上でも変更が確認できました!
--- !u!1 &1828928079の部分はどういう意味か
!u! の後がクラスIDで、
& の後がファイル内で一意に割り振られるオブジェクトIDです。
クラスIDの一覧はこれです。
docs.unity3d.com
ここにも書いてあるとおり、自分でスクリプトを作成してアタッチするとクラスIDは114(MonoBehaviour)になるそうです。
おわりに
ある程度は直接unityファイルから編集できそう(バグ起きそうだけど)なので、うまいことシーンファイル内部を参照できれば不思議なことができそうです。
共同開発でしばしばコンフリクト起こす場所でもあるので、内部が少し把握できると対策案が組めそうですね。