こんにちは、エンジニアのオオバです。

CEDEC2019に聞き手として参加させて頂き「Unity2018/2019における最適化事情」セッションを元にパフォーマンス関連についてまとめます。

→11万文字で徹底解説した「DOTweenの教科書」Unityアニメーションの超効率化ツールはこちら

既存機能のアップデート

cedec2019気になったUnity情報パフォーマンス編_0

既存機能アップデートに関するスライドですが、気になったものだけ取り上げて説明します。

AnimatorのGameObject非アクティブ化時のリセット対策

※Unity2018.1から対応

Animator.keepAnimatorControllerStateOnDisable APIのことでこれをtrueにすると非アクティブにしてもステートが残ります。デフォルトfalseで、非アクティブ時にステートのバッファをクリアしているようです。

Unity - Manual: Unity Manual

ParticleSystemのGPU Instancing対応

※Unity2018.1から対応

通常WorkerThreadのParticleSystem.GeometryJobでParticleSystemのメッシュ結合処理をしています。CPU側でメッシュの結合をしてGPUに送り、パーティクルを表示させています。

cedec2019気になったUnity情報パフォーマンス編_1

GPU Instancingを有効にすると、CPUで処理しているメッシュ結合がなくなり、GPU側でコピーされるようになり、処理の高速化が期待されます。
※GPU Instancingを有効化するとWorderThreadのGeometryJobはいなくなります。

RenderModeがMeshの時かつ、Enable Mesh GPU Instancingにチェックが入っていないとGPU Instancingは有効になりません。

cedec2019気になったUnity情報パフォーマンス編_2

またUnityが用意しているシェーダー(Particle/Standard Unlitなど)なら対応していますが、自作で書いているものはそれに倣って修正する必要があります。

【Unity】パーティクルをGPU Instancingで描画してみる & 対応シェーダーを自作してみる - テラシュールブログ
詳しくはこちらの記事で。

PhysXのアップデート

cedec2019気になったUnity情報パフォーマンス編_3

cedec2019気になったUnity情報パフォーマンス編_4

スライド画像の通りです。

Profilerのアップデート

cedec2019気になったUnity情報パフォーマンス編_5

上図のProfilerアップデート概要の通りProfilerが大規模にアップデートされています。
分かりやすいものは以下箇条書きしています。

特にIL2CPPビルド後のDeepProfilingは待ち望んでいました。(まだベータで使えないけど)

ここからは軽い説明付きです。

Hierarchyでメインスレッド以外が閲覧可

※Unity2019.3から対応

cedec2019気になったUnity情報パフォーマンス編_6

このようにメインスレッド以外の状態をHierarchyから見れるようになりました。
(今までTimelineでしか確認することはできなかった)
ただしぼくの環境(Mac & Unity2019.3.0b1)では、プルダウンを切り替えようとすると以下のヌルポが出て確認できませんでした。

NullReferenceException: Object reference not set to an instance of an object  
UnityEditor.EditorWindow.Close () (at /Users/builduser/buildslave/unity/build/Editor/Mono/EditorWindow.cs:919)  
UnityEditor.StatelessAdvancedDropdown.ResetAndCreateWindow () (at /Users/builduser/buildslave/unity/build/Editor/Mono/Inspector/AdvancedDropdown/EditorGUI/StatelessAdvancedDropdown.cs:21)  
UnityEditor.StatelessAdvancedDropdown.DoLazySearchablePopup (UnityEngine.Rect rect, System.String selectedOption, System.Int32 selectedIndex, System.Func`1[TResult] displayedOptionsFunc, UnityEngine.GUIStyle style) (at /Users/builduser/buildslave/unity/build/Editor/Mono/Inspector/AdvancedDropdown/EditorGUI/StatelessAdvancedDropdown.cs:125)  

ProfilerReader

GitHub - unity3d-jp/ProfilerReader: The library that read Unity profiler binary log directly
Unity黒河さん作のアセット。
ProfilerのログをCSV書き出しをしてくれます。これを使ってテストの自動化を行うといったことをklabのセッションでやっていたようです(セッションは見ていないですが、公開されているスライドはとても有益でした)
Android向けUnity製ゲーム最適化のためのCI/CDと連携した自動プロファイリングシステム

CreateGPUProgramの詳細が表示されるようになった

※Unity2019.3から対応

cedec2019気になったUnity情報パフォーマンス編_7

ShaderVariantが切り替わる際の詳細が表示されるようになりました。

Profilerに任意のデータを埋め込めるFrameMetaData

※Unity2019.1から対応

Profilerに任意のデータを埋め込めるようになりました。

黒河さんのTweetで紹介されていました。

公式リファレンス

OnDemandRendering.renderFrameIntervalの追加

※Unity2019.3から対応

cedec2019気になったUnity情報パフォーマンス編_8

描画処理のみスキップさせることができるようになりました。

OnDemandRendering.renderFrameInterval = 1;  

例えば上のようにOnDemandRendering.renderFrameIntervalに1を代入すると、1フレームずつスキップされます。ターゲットフレームが60だった場合30FPSになるようなイメージです。2を代入したら15FPS。

元に戻したいときは0を代入します。

画面更新が不要な場合の処理負荷軽減をさせることができますし、描画だけを止めたい時に1行書くだけで実装できるのはとても楽です。

少し余談

OnDemandRendering.renderFrameIntervalはUnity2019.3から対応とのことですが、PlayerLoopをカスタマイズすればUnity2018でも対応は可能です。ショートカット的なAPIが追加されたということになります。

MeshAPI V2

NativeContainerを利用した動的メッシュ生成APIの追加が予定されているとのことです。これにより、GCAllocしない、また高速化が期待できます。実装タイミングはUnity2020辺りの予定らしいです。

最後に

今回パフォーマンス編としましたが、LWRP、DOTSについては外しています。DOTSについては別記事で執筆予定です。
聞き漏らした内容もあると思うので資料公開された際には、誤記がないかチェックしようと思います。また、早くUnity2019.3が安定化してもらいたいと思いました。

オススメ記事