[Unity]Unity ECS v1.3.2を使ってゲームを作ってみました (1)―紹介編

[Unity]Unity ECS v1.3.2を使ってゲームを作ってみました (1)―紹介編

はじめに

はじめまして、 第二事業部 エンジニアの孫(ソン)と申します。
普段からUnity ECSを勉強しながら、ゲーム開発を行っています。
ネットに公開されている記事は概念的な説明が多く、
実戦的にゲームを組み立てた内容が少ないです。
そこで、わずかながら個人の経験を共有させていただきます。

Unity ECSで得られるメリット

Unity ECSは、structでEntity、Component、Systemを作成できるようサポートしています。これにより、データ処理をSIMDに変換する最適化コンパイラ[Burst Compiler]が活用可能になります。
さらにSystem内でJobを使いScheduleParallel()を実行することで、配列データの走査を均等に分割し、マルチスレッドで並行処理が可能になります。
上記のUnity DOTSはECSなしでも使用できますが、ECSアーキテクチャと組み合わせることで、DOTSの利点を最大限に引き出し、高速なコードが書きやすいと思います。

DOTSを使うとどのぐらい速くなるか?

CodeMonkeyさんのJob検証動画では下記のような検証がなされています。
1フレームごとに実行する処理で、1000個のSpriteオブジェクトに対してmath.exp10(math.sqrt(value));を1000回実行しています。
以下がその結果です。(動画 20:43 以降でまとめられています)

foreach ScheduleParallel +Burst Compiler
処理負荷 ms 140ms 40ms 4ms
フレームレート fps 7fps 21fps 220fps
速くなった倍率 1倍 3倍 30倍

foreachで重い計算処理を実行すると、140msの負荷がかかり、7fpsしか得られませんでしたが、「ScheduleParallel」を使用すると約3倍速くなり、さらに「Burst Compiler」を加えると30倍の速度向上が見られたとのことです。

今回作ったサンプルゲーム

約1000体のハイポリゴンモデルを作成しながら高fpsを保てるかどうかのサンプルゲームを作成しました。
動作環境はCPU Xeon E3-1230V5 3.40GHz、GPU NVIDIA Quadro K1200です。
Unity ECS未使用だったときは50体ほどで60fpsを保てなくなりましたが、実際に試して60fps保てた1000体まで60fpsを維持することが出来ました。

プレイヤー(カメラだけ)は敵(ユニティちゃんコスプレイヤー)の魅力に耐えながら勝利を目指すゲームです。
シャッターチャンスの良い角度で写真を撮ることで、敵を退場させることができます。

レンダリング最適化のアプローチ

サンプルゲームではハイポリゴンモデルを使って、Unity ECSパフォーマンスの向上を検証しました。
CPUの処理よりもGPUの描画がボトルネックになりやすいです。サンプルゲームではハイポリゴンモデルの描画が非常に負荷が高いです。
そのため、Unity最新の大量描画APIであるBatchRendererGroupを使用したEntities Graphicsパッケージを導入しました。
シェーダーも色々と改修し、DOTS Instancingと頂点シェーダーアニメーションを追加することで、アウトライン付きの高価なアニメシェーダーの見た目を保ちながら、約1000体のハイポリゴンモデルを60fpsで描画することができました。
Androidの端末でもLODを強めることで、約1000体のハイポリゴンモデルを出すことができました。

次回予告

今回の記事はここまでとなります。
次回の投稿では最新のECSの書き方を説明します。興味を持った方は、ぜひお楽しみください。

参考資料

Getting Started with the Job System in Unity 2019
【Unity】ECS向けのアニメーションシステムを実装してみた
Entities[1.3.2]Changelog
© Unity Technologies Japan/UCL