Unity

[Unity] iOS実機にてAssetBundle経由でTilemapを含むSceneを読み込んでクラッシュする

⚙実行環境

  • Unity2017.3.1f1

📝現象

  • SceneをAssetBundleに格納して実行時に読み込む運用を行っている
  • iOS実機にて特定のシーンを読み込んだ際にクラッシュした

🤔仮説

下記から Tilemapを含むSceneをAssetBundle経由で読み込み実行しようとした際にクラッシュする という仮説が立てて調査する

  • Tilemapを含まない汎用的なシーンにおいてクラッシュしない
  • AssetBundleから読み込まず、Sceneを含めてビルドして検証するとクラッシュしない

💡原因

アプリ側でTilemapを未使用かつ Strip Engine Code が有効な時、ビルド時にTilemapに関する実行コードは削除される。これによりAssetBundleで動的に Tilemap を含むSceneを取得した時に実行することが出来なかった。

(逆にアプリ側でTilemapを使用しているのであれば、ストリップされないのでこの問題は発生しない)

🗑Strip Engine Codeについて

Strip Engine Code はモバイル向けの最適化オプションの1つで、ビルドする際Unityエンジンから未使用コードを削除することでビルド容量の軽量化を図ることができる。Strip Engine Code は以下の条件で適応することができる。

  • IL2CPPを使用している
  • PlayerSettings => Other Settings にある Strip Engine Code が有効である

StripEngineCode.png

🛠解消

Strip Engine Codeを無効にする

Strip Engine Codeを無効にしたビルドで検証し、クラッシュしないことを確認した。この状態だと容量が増えた状態になるので、別の対処法を取る。

link.xml に使用するコードを記載する (推奨)

Unity - Manual: Managed bytecode stripping with IL2CPP

上記に記載されているが link.xml というファイルを作成し、Assetsフォルダの直下に配置することで、ストリップされないコードリストを定義することが出来る。
今回は UnityEngine.Tilemaps.Tilemap / UnityEngine.Tilemaps.TilemapRenderer を定義する。

link.xml
<linker>
    <assembly fullname="UnityEngine">
        <type fullname="UnityEngine.Tilemaps.Tilemap" preserve="all"/>
        <type fullname="UnityEngine.Tilemaps.TilemapRenderer" preserve="all"/>
    </assembly>
</linker>

link.png

上記のような link.xml を配置した状態で Strip Engine Code を有効にしビルドして検証したところ、クラッシュが発生しないことを確認した✨

📗参考