やったこと

 趣味でUnity 2D/WebGLを使ったドット絵ゲームをつくろうと色々やっている人間です。

 久しぶりに新しいゲームの開発を進めていたところ、iOSブラウザで起動しない事象にヒットしました。調査していくといくつかの対処案が見つかりましたが、試せど試せど解決に結びつかず困ったので、備忘録として残しておきます。ちょっと疲れた。

 結論としては以下。

・2022年5月現在、iOS15とWebGL / WebAssemblyの相性が悪いため発生している事象

・Unity Editor内のライブラリソースファイルを編集することで解決

 この記事には様々な試行錯誤の経緯を残していますが、もし対処方法だけ参照したい場合は該当の章までショートカットしてね。

今回の環境

 今回私がつまづいた環境は以下のとおりです。上記の通り、今回はiOS15とWebGL / WebAssemblyの相性に依るところが原因のようですが、明確にこのバージョンが悪い、という部分は調査しきれていないのであしからず。。

macOS Monterey 12.3

 ハードはMacBook Air (M1, 2020) を使用しています。後述のAppleシリコン対応のUnity Editorが使いたくて、昨年2021年にWindowsより乗り換えました。

Unity Editor: 2021.2.7f1

 Apple M1シリコン対応のStableバージョンを使っています。ビルドが爆速で快適。

iOS 15.5

 今回の件には多分直接関係ありませんが、ハードはiPhone 12 miniを使用しています。

Safari / Google Chrome v102.0 (いずれもfor iOS)

 今回の件はOS(OS組み込みのWebAssenbly)依存のようなので直接関係はなさそう。

困ったことと調査

事象発生の経緯

 趣味でUnityをちょいちょい触っています。Store配布のアプリというより、Webブラウザでサクッとプレイできる方が好みなので、ビルドターゲットはWebGLです。

これは直近のたのしいミニゲーム

 2021年中頃まではいくつか既存の古ーーーいプロジェクトを継ぎ足し継ぎ足しで来ていました。
 今回、重い腰を上げて新しいゲーム(っていうほどのものじゃないけど)の作成に取り組むべく、せっかくなのでクリーンなプロジェクトを立ち上げ、作成に取り組み始めたところ、以下のステップでつまづいた次第です。

  1. 新しいプロジェクトを実装、Editor内で起動する → ◎
  2. WebGLとしてビルド、ローカル起動する → ◎
  3. WebサーバにアップロードしPCブラウザで起動する → ◎
  4. ③をiOS 12端末にて起動する→◎
  5. ③をAndroid端末で起動する → △ → ◎ ※今回の本筋とは異なる部分でちょっと躓いたので別途記事にします
  6. ③をiOS 15.4端末にて起動する → 動作しない!!!
  7. ⑥端末で別のブラウザ(Safari/Chrome)を試してみる → 動作しない!!!

事象の詳細

 「動作しない」とは、具体的には「HTML内に埋め込まれたUnity Canvas内の初期ロード画面から画面遷移しない」状況です。

まっくら
ちゃんと起動するとロゴマークが表示(キャプチャがへたくそなのでちょっと暗い)

 上記の通り、いくつかの動作環境の中でも、『WebサーバにアップロードしたものをiOS15.4端末で起動』しようとしたときにのみ発生しました。正確には、同じWebサーバへのアクセスでiOS 12/Android端末では動作したので、Webサーバ側には大きな問題は無さそうです。(ハード依存は考えないとして)iOS 13以降の環境が被疑であると切り分けましたが、我が家にはiOS 15.4端末しかなかったので、詳細はわからず。
 なお、上記の通り、ブラウザ依存でも無さそうな雰囲気です。

デバッグ

 ブラックボックス的な事象の切り分けができたので、詳細にデバッグします。

モバイルブラウザのデバッグってどうすればいいねん

 PCブラウザでは動作するけどモバイル端末ではしない、という状況が初めてだったので、まずはどうデバッグすればよいか調べるところから(いつもはPC / Chromeのデベロッパーツールを使えばよかった)。。。初歩的。。。

 どうやら、MacのSafariでiOS端末の表示ページをリアルタイムに監視できる『Webインスペクタ』なるものがあるとのこと。便利だなぁ。
 詳細はググっていただけるとなんでも出てきます。このへんとか参考にさせていただきました。ちなみにSafariだけじゃなくってChromeさんでも似たようなことができるっぽい。

確認結果

 以下な感じのエラーを吐いていることがわかりました。

Uncaught RuntimeError: memory access out of bounds
    at wasm-function[8336]:324
    at wasm-function[8331]:257
    at wasm-function[1315]:929

 メモリ????

対策の調査

 上記の通り、「Uncaught RuntimeError: memory access out of bounds」を吐いていることがわかったので、このメッセージを手がかりにGoogleさん検索。

 すると、解決策がヒットしました。

A)WebGLの許容メモリ上限の拡張 → 解決せず

 上記のエラーに類似するもので一番ヒットしたのがこれ。

参考①:WebGL: RuntimeError: memory access out of bounds.

参考②:Unity:WebGLでメモリエラーに苦しんだ話

参考③:Unity:WebGLビルド「Out of memory…」で起動できない時の対処

 『ブラウザ側でパニックにならないよう、WebGLにて動作メモリ量の上限を規定している。ビルド時のPlayer Settingsやビルド後のjsファイルにてメモリ上限を拡張設定することで解決できるよ。』というもの。

 すべての設定項目を順に試してみようとしたのですが、どうもいずれも見当たらない。Player Settingsに『Memory』の項目があるものの、なんとなく違いそう。

 更に色々調べてみると、なんとUnity 2019以降はメモリ上限を動的に制御している、とのことで、上記設定は廃止されたみたいでした。
 そもそも、ビルドされたファイル群のサイズは合計5MB程度だったので、そんなメモリを食っているとも思えない。。。

B)iOS 15との相性問題→解決!

 上記で四苦八苦していたところに、以下の公式フォーラムの投稿を発見。

iOS 15 + WebGL 2 issue

 読み解くと、なんかiOS15とWebGL / WebAssembly 2との仲が悪いらしい。iOS側の実装に問題があるから、今Apple側にかけあってるんだ、みたいなことも書かれています。
 英語が不安だったこともあり、以下の記事も併せて参考にさせていただきました。かんしゃ。。。

iOS15.4のSafariでUnity WebGLが動かない問題の対応策

 公式フォーラムの投稿は2022年5月末現在でもやりとりが行われており、上記のnote記事から進捗もありましたので、最新情報は投稿を確認したほうがよさそうです。なお、まだApple側の対応はなさそう。

 ここで記載されている対応策:Unity Editorライブラリの編集を行うことで、私の環境でも事象が改善しました。

有効だった対処

 前述の通り、公式フォーラムの投稿に対処の記載がありました。

Technically, the fix is for cpp, not c#. To add the lines, edit the file il2cpp/libil2cpp/metadata/GenericMetadata.cpp in a text editor. You can find this file in:
MacOS:
/Unity.app/Contents/il2cpp/libil2cpp/metadata/GenericMetadata.cpp
Windows:
/il2cpp/libil2cpp/metadata/GenericMetadata.cpp

Find the line

const Il2CppType* GenericMetadata::InflateIfNeeded

add the line #pragma clang optimize off on the line above it.

Find the end of the function and add the #pragma clang optimize on line below it.

iOS 15 + WebGL 2 issue

 上記の通り、Unity Editorのライブラリソースファイル”GenericMetadata.cpp”に手を加え、ビルドし直します。
 なお、私の場合、このソースファイルのバックアップを同じフォルダに設置してしまってビルドを阻害するとかって謎ミスをしてしまったので真似しないように注意してください。。。

 前述の記事ではWindows環境ですが日本語での手順が記載されています。ありがたいね。Macでのファイルパスは上記の通り。

解決した!!!

 上記の通り、iOS15 と WebGL / WebAssembly 2との相性問題をUnity Editorのライブラリ編集という形で解決できました。が、やっぱりこれはただの暫定対処なので、Apple側の対処を期待したいです。。iOSのアップデートがあったらまたなんかありそうでこわい。。。

 あとはやっぱり、Unity 2019以前のいろいろな知見に振り回された(というか私が勝手に迷子になった)ところもあったのは反省点です。。