初透光です()
リポジトリはこちらに置いておきます。LICENSEはMITですので、どうぞご自由にお使いください。
執筆者環境
- Unity 2018.2.6f1
- ECS 0.0.12-preview.11
問題提起
Entity Component Systemのバージョンは上がる度にかなり破壊的変更が入ります。
大体においてより性能が上昇するよい方向への変化で歓迎できますが、性能向上のために動かなくなる環境もあります。
WebGL おめーのことだよ!!!
WebGLの限界
- マルチスレッド処理ができない
- C# Job Systemが死んだ! この人でなし!
- IntelのSpectreとMeltdownさえなければ今年中にWebAssemblyでマルチスレッド処理を行えていたはずだった (´・ω:;.:…
- AOT
- System.EmitやSystem.Text.RegularExpressionが死んだ! この外道!
- OpenGL ES 3.0相当の表現力しかもたないシェーダーコード
- マルチスレッドできないのにComputeShaderが使えないとか追い打ちやめてクレメンス……
それでも、ECSで立ち向かわなくちゃいけないんだ!
Unity1週間ゲームジャムの提出形式がWebGLだから!
解決策
@mao_ さんがTwitterで呟いた「WebGLでECSを使う方法」はこちら。
解決策その2
できれば最新版使いたいので、最新のECSをWebGLに対応させました。
対応方法
- JobComponentSystemを削除
- 依存するもの全て削除・修正
- IJobParallelForComponentData削除
- IJob/IJobParallelForを実装した構造体をScheduleしていた部分を同期的に書き換えた
- IJobParallelForはfor文にし、return文を適宜continueに書き換えた
- Job構造体のフィールド名をリファクタリングでローカル変数の名に書き換えることでコピペ効率を上げた
- JobHandleを扱う部分を削除した
- JobComponentSystemを継承していたSystemを書き換えてComponentSystemを継承するように変更した
- NativeContainerのAllocatorのうちTempJobを全てTempに書き換えた
このような手順を丁寧に踏むことでECSがWebGLで動くようになりました。
苦労した点
メモリリーク周りでエラーが嵐のように吹き荒れました
- Unity.Collections.DeallocateOnJobCompletionを付与されていたNativeContainerを書き換えた後Disposeし忘れていた
- 最適化のためにコードパスの枝刈り(早めのreturn)をしていたが、そうするとDisposeし忘れたコードパスが多々存在した
結論
これを使って9月3日からのゲームジャムに最新のECSで挑むことが可能です。