トーフメモ

主にゲーム制作

シーンファイルの正体【Unity】

f:id:tofgame:20190428235106j:plain

Unityを使っているとき、ほぼ確実に使う「シーンファイル」。
拡張子は.unityで、シーンを保存すると作成されます。

けどこれ何を保存してるんだろう・・・
シーンの情報が入っているんだろうけど・・・
・・・

気になったので調べました!
今回使用したUnityのバージョンはUnity2018 3.7f1です。

シーンファイルの形式

YAML」という名前のHTMLやXMLと似たようなマークアップ言語らしいです。

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}に変えてみます!

f:id:tofgame:20190430032212p:plain
外部変更が検知され、

f:id:tofgame:20190430032348p:plain
Unity上でも変更が確認できました!

--- !u!1 &1828928079の部分はどういう意味か

!u! の後がクラスIDで、
& の後がファイル内で一意に割り振られるオブジェクトIDです。
クラスIDの一覧はこれです。
docs.unity3d.com
ここにも書いてあるとおり、自分でスクリプトを作成してアタッチするとクラスIDは114(MonoBehaviour)になるそうです。

おわりに

ある程度は直接unityファイルから編集できそう(バグ起きそうだけど)なので、うまいことシーンファイル内部を参照できれば不思議なことができそうです。
共同開発でしばしばコンフリクト起こす場所でもあるので、内部が少し把握できると対策案が組めそうですね。

参考にしました

docs.unity3d.com