Unity5.5から推察するUnityの前方互換性について

# プロローグ
2017年春のこと、Unity5.5でexportしたunitypackgeをUnity5.4にインポートしたところ..


シーンが壊れたり、時にはUnityがクラッシュしたり(！)しました。

どんな原因で問題が発生するのか調査したのですが
「これが原因っぽい..?」というところまで調べたのでまとめました。
あくまでも推察による内容なのでご了承ください。


# 互換性について

互換性には主に以下があります。(wikipediaより)

|名前|概要|
|:--|:--|
|上位互換性|上位の製品が、下位の製品の機能も有する|
|下位互換性|下位の製品が、上位の製品の機能を有する|
|前方互換性|新しいシステムのデータなどが古いシステムで使用できる|
|後方互換性|古いシステムのデータなどが新しいシステムでも使用できる|

また、Unityは現在一般向けにPersonal, Plus, Proのグレードがあり、
Unity2017.x, Unity5.x, Unity4.xというバージョンがあります。

今回はUnity5.5のデータをUnity5.4で扱おうとして不具合があったので
「Unity5.4ではUnity5.5のデータについて前方互換性がない状態」となります。

ー
ちなみに後方互換性については、
Unityのアーカイブページにチラッと書いてあったり、
https://unity3d.com/jp/get-unity/download/archive
英語のドキュメントだとアップグレードガイドがあります。
https://docs.unity3d.com/Manual/UpgradeGuides.html

# 調査1: 前方互換性が完全になくなるバージョンを探す

Unity5.3, 5.4, 5.5, 5.6でそれぞれUnityの初期シーン
(MainCameraとDirectionalLightのみある状態)
をexportし、0.1前のバージョンで読み込んでみると結果は以下の通りでした。

|名前|概要|
|:--|:--|
|5.6のunitypackageを5.5で開く|✓|
|5.5のunitypackageを5.4で開く|× (シーンが壊れる)|
|5.4のunitypackageを5.3で開く|✓|

Unity5.5で何かが変わっているぽい..?

※カメラとライトだけのシーンで調査したので、5.4→5.3なども互換性があるとは言えない状態です。念のため。

# 調査2: 原因箇所を探す

Unity5.4, Unity5.5のシーンファイル(.unity)をTextEditorで開くと以下のようになっていました。

Unity5.4

```
:
--- !u!1 &619574159
GameObject:
  m_ObjectHideFlags: 0
  m_PrefabParentObject: {fileID: 0}
  m_PrefabInternal: {fileID: 0}
  serializedVersion: 4 //<---ちがう
  m_Component:
  - 4: {fileID: 619574164} //<---このあたりもちがう
  - 20: {fileID: 619574163}
  - 92: {fileID: 619574162}
  - 124: {fileID: 619574161}
  - 81: {fileID: 619574160}
  m_Layer: 0
  m_Name: Main Camera
  m_TagString: MainCamera
  m_Icon: {fileID: 0}
  m_NavMeshLayer: 0
  m_StaticEditorFlags: 0
  m_IsActive: 1
--- !u!81 &619574160
:
```


Unity5.5

```
:
--- !u!1 &2018136905
GameObject:
  m_ObjectHideFlags: 0
  m_PrefabParentObject: {fileID: 0}
  m_PrefabInternal: {fileID: 0}
  serializedVersion: 5 //<---ちがう
  m_Component:
  - component: {fileID: 2018136910} //<---このあたりもちがう
  - component: {fileID: 2018136909}
  - component: {fileID: 2018136908}
  - component: {fileID: 2018136907}
  - component: {fileID: 2018136906}
  m_Layer: 0
  m_Name: Main Camera
  m_TagString: MainCamera
  m_Icon: {fileID: 0}
  m_NavMeshLayer: 0
  m_StaticEditorFlags: 0
  m_IsActive: 1
--- !u!81 &2018136906
:
```

serializedVersionが4から5になっています。ちなみに
Unity4.7は「serializedVersion:4」
Unity2017.1は「serializedVersion:5」
だったのでGameObjectのserializedVersionは頻繁にあがらないバージョンのようです。
serializedVersion以下m_Componentのデータ構造は別のものになっています。

# 調査3: 復旧可能か確認

上記のUnity5.5のシーンファイルをUnity5.4でimport後、
テキスト編集でserializedVersion:5形式からserializedVersion:4形式に変更すると
シーンは壊れませんでした。

参考にしたのは以下ページです。

テキストシーン形式
https://docs.unity3d.com/ja/540/Manual/TextSceneFormat.html

▼スクリーンショット

Unity5.5で動作するシーン
<img width="640" alt="e.png" src="https://qiita-image-store.s3.amazonaws.com/0/19692/e4318a2b-7c51-2198-1403-f94958f29165.png">

Unity5.4に持ってくると壊れるが..
<img width="640" alt="a.png" src="https://qiita-image-store.s3.amazonaws.com/0/19692/9839ab41-bc12-a528-7665-25fe39bc2edd.png">

テキスト編集でシーンファイルを編集すると..
<img width="220" alt="b.png" src="https://qiita-image-store.s3.amazonaws.com/0/19692/e0247277-48c1-7ee7-d556-10e9f3b99ea4.png"> <img width="200" alt="c.png" src="https://qiita-image-store.s3.amazonaws.com/0/19692/b4846f48-0098-4e2f-f19a-5641c3f54770.png">

ふっかつ！

<img width="640" alt="d.png" src="https://qiita-image-store.s3.amazonaws.com/0/19692/5861b6ce-b394-b09e-111c-8599587040d8.png">


# まとめ

以下推察ですがまとめです。


- 各コンポーネント(※1)はserializedVersionを持ち、serializedVersionごとに決められたデータ構造を持つ
  - serializedVersion:1の場合は省略可能っぽい
- serializedVersionが上がったコンポーネントは、ロードできないなど意図しない動作をする可能性がある
  - 新しいデータ構造を古いUnityが知らないため(だと思う)
- Unity5.5ではGameObjectのserializedVersionがあがっているため、Unity5.4以下でUnity5.5のデータを開こうとするとシーンが壊れたりクラッシュしたりする
  - GameObjectはPrefabやSceneにも使用されているため(だと思う)

(※1)UnityマニュアルにまとめられていますがUnity5.4時点で236種類ありました。
YAMLクラスIDリファレンス
https://docs.unity3d.com/ja/540/Manual/ClassIDReference.html

ー
AssetStoreにはきちんとexport時のUnityバージョンが記載されているので、
古めのUnityを使っている方は↓ここに注意

![z.png](https://qiita-image-store.s3.amazonaws.com/0/19692/03d6e2b2-5bfc-3125-a68d-d23928c309ca.png)