[Unity]WebGL出力をスマホのブラウザで実行する

Unity 上で作成したアプリは WebGL で出力でき、ブラウザで実行できます。が、公式マニュアルには
> Mobile devices are not supported by Unity WebGL.

と、スマホのブラウザには対応していない旨が記載されています。

https://docs.unity3d.com/2021.2/Documentation/Manual/webgl-gettingstarted.html

が、実際のところは、動きます。公式にサポートされていないだけで、ほぼ、動くんですよね。

https://twitter.com/dsedb/status/1389844189819523074

以下は、「動かないものを動かす」というよりは、「動かない風な挙動を取り除く」という、ほとんど表層のテクニックになります。

なお Unity 2021.1.5f1 を使用していますが、Web Assembly が有効になった 2018.2 以降、基本的な状況は同じと思われます。また、今回はレガシーレンダリングで試していますが、URPでも動くはずです。ただしURPではいくつかの制約を回避する必要があるので、動作実験をするなら現時点ではレガシーレンダリングがよいです。

# ステップ1.普通にビルドする

まずは任意のプロジェクトでビルドし、PC上のブラウザで動作するのを確認しましょう。
それをスマホで実行するのは、自分でHTTPサーバを立てるのが便利でしょう。多少のネットワークの知識が必要ですが、ここでは省略します。

スマホで実行すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90046/3ae73fa4-fa23-8a1e-f191-f73bee74e0c4.png)

こんな表示が出ます。まあ、これを出されたら「ああダメなんだな」って思わされますよね。待っているとこのメッセージは消えるんですが、画面は真っ黒なままです。

なお、ここのビルドで生成されたファイルをステップ３で使用するので、スマホで表示するテストはしなくてもいいですがビルドだけはやっておきましょう。

# ステップ2. Graphics API を WebGL 1 にする

スマホで画面が出ないのは Graphics API に WebGL 2.0 が選択されているからです。 Project Settings を開き、プレイヤーの
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90046/961b0cbe-c1c4-5069-95c9-d341a3db2c06.png)
この「自動グラフィックスAPI」のチェックを外し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90046/297df2a0-de4e-be09-7d8b-82c6938b1adb.png)
WebGL 1 を追加し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90046/d88a0cd7-0146-31dd-7f58-a6e873647373.png)
WebGL 2 を削除してこんな状態にします。

実はこれでもう、スマホで画面が出るようになります。ただし WebGL 1 にすることでいくつかの描画アルゴリズムを利用できなくなります。
WebGL 1 と WebGL 2 の違いは以下にまとめられています。

https://docs.unity3d.com/Manual/webgl-graphics.html

# ステップ3. WebGLTemplates を設定する

警告メッセージ "WebGL builds are not supported on mobile devices." を出さないようにしましょう。
Assets/WebGLTemplates というフォルダを作成します。これは予約フォルダ名で、HTMLのテンプレートを格納できます。
さらに MyTemplate（なんでも良いです）というフォルダを作り、その下に、ステップ１のビルドで生成された
- index.html
- Templates（フォルダ）
をコピーして配置します。

配置した index.html をテキストエディタで開き、下のほうの

```javascript
        unityShowBanner('WebGL builds are not supported on mobile devices.');
```

という行を削除します。

Project Settings の Player に、配置したフォルダが WebGLテンプレート のところで選べるようになっているはずです。MyTemplate を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90046/53cfc5d7-8eab-8fb9-3556-3690982c404a.png)

これで、次のビルドからモバイルでの警告が出なくなります。
なお、特に圧縮設定を変更した場合に、 index.html がそれに対応している必要があるのに注意してください。問題が起きたらこのステップをやりなおしましょう。

# 完了
以上です。やってることはほぼ、グラフィクスAPIを WebGL 1 にするだけですね。

## おまけ：サーバ設定
なお、HTTPサーバに応じた対応が必要になるケースがあるようです。

https://docs.unity3d.com/ja/2021.1/Manual/webgl-server-configuration-code-samples.html

私のテストの範囲ではこの対応をすることなく動作させることができましたが。

## おまけ２：メモリ設定

スマホブラウザおける問題として挙げられるのは、使用可能なメモリ容量です。

https://blogs.unity3d.com/2018/08/15/webassembly-is-here/

この記事にメモリ上限の設定方法があります。

```C#
PlayerSettings.WebGL.emscriptenArgs = "-s WASM_MEM_MAX=512MB";
```

メモリ上限を定めることで明確に「動作しない」ことをエンドユーザに伝えることができます（的なことがそこに書いてある）。

# まとめ
動くと言っても、やっぱり非対応は非対応です。そんな、公式にはサポートされていないものとどう向き合うか、という話ですが、ビルドしたものが動作してしまえば、それは安定していると言えます。であるなら、商売に利用することも検討していいと思うんですよね。スマホの性能も上がってきてますし。もちろん性能には幅があるので、おまけ２で触れたような、動かない条件を定めて通知できるようにすることが肝要と思います。また、継続的にUnityの最新バージョンに追随する計画がある場合は、慎重になったほうがいいでしょう。

ちょっとしたゲームの試作を知人に見てもらう、のようなケースにおいては、今回の対応でスマホで動作できるようにしておくのはとても有効だと思います。

# P.S.
実は、今回の私の調査はサイズ削減に大半の労力が割かれていたんですが、情報単位は小さい方がよかろうということで、この記事では WebGL 出力のスマホ動作のみに絞りました。スマホでゲームをプレイしてもらうにはサイズの最適化が肝要と思いますが、総合的な話でもあり、書き始めると膨大になりそうです。

# 参考
WebAssembly is here!
https://blogs.unity3d.com/2018/08/15/webassembly-is-here/

Unity WebGL Loading Test
https://github.com/JohannesDeml/UnityWebGL-LoadingTest