【Unity】 DOTS(ECS)をWebGLで使う場合は思った以上にパフォーマンス出ないよって話
DOTSをWebGLで...だと?
またまたUnityの話題。DOTS(ECS)のお話だよ。
【RT希望🙌】次回の #unity1week 開催日を決定しました!
— naichi (@naichilab) 2020年1月18日
Unity 1週間ゲームジャム 次回は 2020年02月24日(月) 開催 https://t.co/2uhr9rdqDr
初心者大歓迎のオンラインゲームジャムですので気軽にご参加ください〜!リンク先から過去の作品も遊べます!
Unity1weekが近くなってきて、
「流行りのDOTSでいっちょ神ゲー作ってやろう」
なんて考えてるそこのキミに見てほしいです。
結論から言うとWebGL出力だとJob , Burst使っても
思ったよりもパフォーマンス出ないよ、って話です。
実装について
今回の調査では
「オブジェクトを大量に表示しつつRotateだけ行う」
という簡単な動きだけで計測してます。
細かい実装はほぼこれなんでそっちを読んでもらい、RotateSystemだけ載せます。
#define USE_JOB #define USE_BURST #if USE_BURST using Unity.Burst; #endif using Unity.Entities; using Unity.Jobs; using Unity.Mathematics; using Unity.Transforms; #if !USE_JOB public class RotateSystem : ComponentSystem { protected override void OnUpdate() { var deltaTime = UnityEngine.Time.deltaTime; Entities.ForEach((ref Rotation rotation, ref RotateSpeedComponent rotateSpeedComponent) => { rotateSpeedComponent._rotationAngle += rotateSpeedComponent._rotationSpeed * deltaTime; rotation.Value = quaternion.RotateY(rotateSpeedComponent._rotationAngle); if (rotateSpeedComponent._rotationAngle >= 360.0f) { rotateSpeedComponent._rotationAngle -= 360.0f; } }); } } #endif #if USE_JOB public class RotateSystem : JobComponentSystem { #if USE_BURST [BurstCompile] #endif struct RotateJob : IJobForEach<Rotation,RotateSpeedComponent> { public float deltaTime; public void Execute(ref Rotation rotation, ref RotateSpeedComponent rotateSpeedComponent) { rotateSpeedComponent._rotationAngle += rotateSpeedComponent._rotationSpeed * deltaTime; rotation.Value = quaternion.RotateY(rotateSpeedComponent._rotationAngle); if (rotateSpeedComponent._rotationAngle >= 360.0f) { rotateSpeedComponent._rotationAngle -= 360.0f; } } } protected override JobHandle OnUpdate(JobHandle inputDeps) { var job = new RotateJob() { deltaTime = UnityEngine.Time.deltaTime }; return job.Schedule(this, inputDeps); } } #endif
(雑にdefineでJob、Burstの使う使わないを切り替えれるようにしてます。
実際に使うときはこんなん作らないからね。適当です。)
PCでEntityのみの場合(50000object)
まず、PCでEntity + ComponentSystemだけで50000Object出すと
このぐらいのパフォーマンスになります。
(13~14FPS)
WebGLはどうなの?
unity1weekで使いたい、サクッとgithubで公開したい、
といった方はWebGLでの出力が候補になります。
50000objectだと重すぎて動かなかったので、10000objectまで下げてます。
また、ブラウザはFireFoxで見てます。
結論として
WebGLでDOTS使いたいなら5000object程度に留めておいた方が良さそうです。
過去作った全てを破壊したいUnityちゃん、というゲームでも
1000object以下で収まるように調整してました。
(WebGLではあれ以上街を広げられない)
それでも3倍はいけるというDOTSの実力には脱帽ですね。
誰かunity1weekでドドドッと襲いかかってくるゾンビを
ひたすら撃ちまくるゲームとか作ってください。
補足として
偉大な先駆者maoさんがすでにunity1weekでDOTSにチャレンジされています。
早速遊んでみたのですが僕の環境ではゲームをブラウザで開くと
まともに動かずガクガクで...。
githubにある動画ほどのスムーズさも見えず...。
もしかして自分のPCが弱いのでしょうか?
このぐらいまともに遊べるぜ!って人PCスペック教えてください...。
ソースまで公開されてます!神さま〜〜!
github.com
さらに補足
スーギ・ノウコ自治区さんに教えていただきました!
やはりWebGLは現時点でSIMDとマルチスレッドをサポートしていない様子。
なるほどねー
— スーギ・ノウコ自治区 (@pCYSl5EDgo) 2020年1月21日
回答ありがとうございます
WebGLは現時点でSIMDとマルチスレッドをサポートしていません(各ブラウザベンダーが独自対応していたりはします(それにUnityが対応しているかは別の話))
ですのでプログラムを組む時にJob Systemを使わない方が賢明といえば賢明です
またWebAssemblyの情報まで!
WebGL(WebAssembly)の仕様についてはこちらをご覧いただくと進み具合がわかりますよー
— スーギ・ノウコ自治区 (@pCYSl5EDgo) 2020年1月21日
UnityはForumに散らばっているので探すだけ体力の無駄な感じがありますね……https://t.co/2EmXpMWzyp
ありがとうございます〜。