Unity
AssetBundle

'Strip Engine Code' の幾重にも張り巡らせられる罠


前置き

Unity には 'Strip Engine Code' という機能があって、必要のないEngine側のコードを削ってくれるという便利な機能がある。

ただ、AssetBundle を作るときには注意が必要だ。なぜかというと、AssetBundleはビルドした元のファイルはアプリ本編の方には入れないのが普通で、そうなるとStripされてしまうというわけだ。くわしくはテラシュールブログの「【Unity】Unity 5.3からAssetBundleはどう変わるのか…まとめ」を読んでもらうといいかもしれない。

これを回避するためには「link.xml」というファイルを作ってその中に


link.xml

<linker>

<assembly fullname="UnityEngine">
<type fullname="UnityEngine.GameObject" preserve="all"/>
<type fullname="UnityEngine.Texture2D" preserve="all"/>
</assembly>
</linker>

こんな感じに書かなくちゃいけない。で、↑の


link.xml

              <type fullname="UnityEngine.Texture2D" preserve="all"/>


という部分を必要なコンポーネントを追加しなくちゃいけないということになる。

で、その必要なコンポーネントっていうのがミソで、何が必要かというのが事前にわかるわけではない。イヤ、わからなくはないのだが、一個一個確かめなくてはいけなくて、そもそもAssetBundleを一個一個確認して行く、というのは非現実的だ。

そこで、とりあえず全部AssetBundle をロードしていって、落ちたところを見て、落ちたときのエラーメッセージを確認しつつ、どんなコンポーネントが含まれていなかったということを確認するという地道なことをしていくしかない。

落ちたとき

Could not produce class with ID XXX

というメッセージが出るので、そのIDが本来必要だったコンポーネントのIDというわけだ。


罠1

前置きが長くなった。

で、だ。

今回のエラーメッセージが

Could not produce class with ID 210

という「210」という番号。それを公式のマニュアル「YAML Class ID Reference」を調べると、

210
TerrainInstance

とババーンと書いてある。ほうほう、「TerrainInstance」が足りないんだな、と。


だがそれは罠だ。

いやいやいや、おかしいでしょ。

今時Terrainを使う方がありえないし、そもそもAssetBundleですよ?TerrainをAssetBundleに入れることなんてそうそうない。実際に使っていない。


罠2

さっぱりわからなかったが、ググってみたら同じような質問に回答している人がいて、そこに


The class-ID docs are misprinted.

The actual type is UnityEngine.CoreModule.SortingGroup, not TerrainInstance.

Took me a lot of brute-force testing to get to the solution :) I hope > this saves you some trouble.

Good luck!


ま、要は


それはミスプリントで、本当は「UnityEngine.CoreModule.SortingGroup」であって、「TerrainInstance」じゃないよ。

はっはっは、まいったよね。俺も大変だったよ。じゃあ頑張ってな!


と言ってる。

なるほど、そういうことか。それでは「UnityEngine.CoreModule.SortingGroup」を入れればいいということだな、と。


だがそれは罠だ(2回目)

実際に「UnityEngine.CoreModule.SortingGroup」を入れてもダメで、実際は

「UnityEngine.Rendering.SortingGroup」を入れなくてはいけない。(考えて見たらその通りで、なんで「CoreModule」でのnamespace にしてるんだろう?という。おそらく昔はそうだった的な?)

というわけで、


link.xml

<linker>

<assembly fullname="UnityEngine">
<type fullname="UnityEngine.Rendering.SortingGroup" preserve="all"/>
</assembly>
</linker>

というのが本当に必要なことだったということ。

現場からは以上です。