Unity for Creative 第2回!! 「Unity x WebGLの開発現場最前線」 メモ

Unity x WebGLの開発現場最前線に参加したのでメモを共有します。
メモなので誤字脱字があります。あらかじめご了承ください。

#開発側から見るUnity x WebGLの開発現場最前線
窪田豊氏 株式会社NilOne

##WebGLの今

・そもそもWebGLとは？

 HTML5のCanvas要素にOpenGLを利用して、グラフィックを描画するためのブラウザ仕様
PCのハードウェアを使用してレンダリングすることができるため、高速かつ豊かな表現が可能

2011年にWebGL1.0登場

・WebGLとOpenGLの関係
WebGLはOpenGL ESをベースにブラウザ向けに調整されてできた使用
WebGL2.0のブラウザサポートはまだ実験段階
WebGL2.0ではグラフィック表現能力とパフォーマンスが向上している

・いい点
ハードウェアを利用するため、Flashよりも高速に動作する
プラグインのインストールなく動作

・悪い点
進化が遅い
ブラウザベンダーが実装する必要がある

・リッチなWebゲーム開発はWebGL主流に
Flashが主流だったが、これからはレガシーな技術に
Unity Web Playerは5.3からサポート終了
SilverLightとかあるが動画プレイヤー以外では使われていない

##Unity x WebGLのこれまでとこれから

Unity5.3以前はプレビュー版として提供。商用製品に使用するには危険だった。
大量のアセットバンドルをダウンロードしている過程で固まった

Unity5.3
正式ビルドターゲットに格上げ

##ネイティブゲームと比較したパフォーマンス上の問題
・実行速度が遅い

JavaScriptの動的型付けという特性のため
ただし、いまはasm.jsというサブセットが事前にJavaScriptをコンパイルして動的型付けを回避する技術が使われ、だいぶ改善してる

・マルチスレッド、SIMDは非対応
物理演算などのCPUをたくさん使う処理はネイティブゲームより重くなる

・WebGLゲームのロード時間が長い
WebAssemblyにより、実行速度・ロード時間は改善される

##WebAssemblyとは
C，C++のコードをJavaScriptではなく、ブラウザが解析可能なバイトコードに変換する仕組み

対応するとUnityにより出力されるJavaScriptは3分の1になる　
現在、Unity、ブラウザベンダーは実装中で近い将来に実用化される見込み

##まとめ
実行速度はネイティブ並みとまではいかないが、事前コンパイルの仕組みによりだいぶ改善している
マルチスレッド　SIMDは非対応なので物理演算が苦手

##スマホアプリ開発とは異なる注意点

・ユーザーはブラウザを複数立ち上げて同時起動できる

同時に１端末しかログインさせない排他制御の仕組みが必要
ログイン時にセッションＩＤを発行し、リクエストの正当性をサーバーでチェックする

・ローカルにユーザーデータの保存できない
当然、ＰＣ・ブラウザが異なれば保存領域も異なる
キャッシュ目的でアセットバンドルの保存ならできる

##パフォーマンス注意点

・PlayerSettingからUnityヒープサイズを調整する
16～2032MB
HTMLからでも変更できる

デフォルトでオフになっているので、オンにする

・物理演算などＣＰＵ負荷の高いものはさける
ＣＰＵ負荷をかけない工夫をする

・同梱物の少量化
毎回ダウンロードするので、スマホアプリ以上に気を付ける
極力アセットバンドル化して必要物を必要タイミングで取得

##WebGLxAssetBundle
ブラウザのIndexDBに保存される
容量の上限はIndexDBにの仕様に依存。ブラウザごとに異なる
BPCのストレージの空き容量に依存。空き容量の3分の１程度
FireFox，Safariは無制限

Browser Storage Abuserで確認できる

##こまごまとした注意点

・WebGL経由でHTTPリクエストを束した場合、FireFoxではHTMLヘッダーにMimetTypeがついていない
RailsでMimeTypeに応じたViewを返す処理で問題になった
MimeTypeのある　なしにかかわらず、特定のViewを返すように修正

・サーバーレスポンスヘッダにCROS許可の設定が必要
Chromeではindex.htmlはを直接開くとエラーで起動しない

UnityからBuild And Runであればローカルサーバー経由で起動するので開ける

##まとめ
サーバーとの連携に若干、注意が必要
メモリ不足でクラッシュする際は、どこのメモリが不足しているのか、どこの領域がメモリを使い過ぎているのかを把握しておくことが大事

##おすすめアセット
GAF
AssetBundleManager
Mad Compile TimeOptimizer
Better Build Info
P;ayMaker
MVM4uGUI

#Unity x WebGLによる開発・運用
小川陽平氏 株式会社DMM.com
安達大輔氏株式会社DMM.com 

レッドコラプションの話

##AndroidアプリをWebGL対応させる際の注意点の対処

・ロジックの最適化
バトルなどの重い処理
FPSの低下がみられた

WebGLはJavaScript上で動くために、重い処理がある場合にレンダリングが遅延してしまう。
そのため、ロジックの最適化が必要

Unite参照 ここの最適化の話を結構参考にした

ゲームを起動しただけで1GBのメモリを使う
32bitだとメモリが足りない

アセットバンドルのロード処理を変更

・Android版
WWW.LoadFromCacheOrDownload(url, version);
初回ダウンロードを行う

・WebGL版
new WWW(url)
初回ダウンロードは行わない

ドメイン単位でIndexDBに保存される
いくつかの対策方法があるが、キャッシュしない方法を選択

##動画再生処理について

EasyMovieTextureを使用していたが、WebGL未対応

AssetStoreにUnityが提供しているSimpleMovieTexturerがあるので、それを使用

アセットバンドルでダウンロードしてきた動画ファイルのバイトは入れつつ、JavaScriptプラグイン
内部でBlobデータを作成
video.src = URLoreateObjectURL(blob,data);

容量の大きい動画ファイルからBlobデータを作成するためにWebWorkerを使用し、重い処理はスレッド化

##アセットバンドルを取得するが、ブラウザのキャッシュから読まれて更新されない

URLのパラメーターにハッシュ値を付ける

##チャンクベースLZ4のアセットバンドルの仕様について
データ量はLZMAに比べて肥大化してしまうが、ブラウザのメモリ使用率は格段に下がる

##日本語入力する場合の対応について
Unity公式のGitHubで配布されている
https://github.com/unity3d-jp/WebGLNativeInputField

##ブレイクポイントが晴れないのでデバッグがしにくい

頑張る

##IndexDBにブラウザが管理しているメモリに関係するのか

IndexDBは検索キーとデータをペアで保存するためのただのデータベースでしかありません。
ブラウザがこのキーとデータをどのように扱っているかはブラウザごとになる

ローカルファイルの扱いに関しては発展途上

##WebGL開発におけるパフォーマンスチューニングの重要性

・絶対にやったほうがいいこと
プロファイラでボトルネックを探す

・メモリ周りの場合
少量でもいいのでメモリの確保

##メモリ確保

Androidで影響がない程度のメモリ確保だったがJavaScriptだと影響がでかかった

・マルチセッション
CPU＆展開用メモリの確保が大量にできる

非力なＰＣだと落ちやすい状態になっていたことが判明
メンテ後にアセットが大きくなると、メモリが確保できず
一部の通信をシングルスレッドすることで対応

・謎のエラーが大量発生
ゲーム起動時に、謎のエラーが発生

Chromeブラウザだと、WebGLの機能を切っている場合に似たようなエラーが表示される
FirBugやクロームなどでデバッグモードがonになっていると表示されることがある
特殊なライブラリを使用して作成したUnityAssetの場合、全てのコードをノード化することができずに上記のようなエラーを表示

##運用開始前にあったほうがいいもの
JenkinsのビルドマシンをAndroidとWebGLで分ける
現状、WebGLのビルド時間はAndroidのビルド時間の倍はかかっている

##運用にあたって考えること
アプリ、ブラウザ版でバグの出方が違うため、対処法を考えなければならない

・単純にデバッグの量が倍になる

両デバイスに最適化したUIや表現を目指す必要がある。
クリックやタップなどではなく、Pushで統一

・アンドロイドユーザーとブラウザユーザーのプレイ時間の縛り
ブラウザユーザーから時限系は嫌われる

##LWFでWebGLを利用する際の注意点と対処法
LWFでそのままWebGL化すると重い

##対処法
・LWF描画方法の変更
LWFの描画をUIのレンダラで行っていたものを通常の３Ｄレンダラに置き換えた。

・リスト表示部をResctMask2Dを用いる方法に切り替え

ヒープ領域を動的確保から固定確保に変更　768MB
ALLOW_MEMORY_GROWTH=1をALLOW_MEMORY_GROWTH=0に変更
アセットバンドルの細分化
ヒープ領域の縮小