シーンファイルの正体【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ファイルから編集できそう(バグ起きそうだけど)なので、うまいことシーンファイル内部を参照できれば不思議なことができそうです。
共同開発でしばしばコンフリクト起こす場所でもあるので、内部が少し把握できると対策案が組めそうですね。