Unity UIの最適化(三):UnityUIプロファイリングツール

バージョンチェック:2017.3 -Difficulty:上級

UnityUIのパフォーマンスを分析するために使用できる分析ツールがいくつかあります。主なツールは次のとおりです。

  • Unityプロファイラー
  • Unityフレームデバッガー
  • XcodeのInstrumentsまたはIntelVTune
  • XcodeのフレームデバッガーまたはIntelGPA

外部ツールは、ミリ秒(またはそれ以上)の解像度のメソッドレベルのCPU分析、および詳細な描画呼び出しとシェーダー分析を提供します。上記のツールを設定して使用する手順は、このガイドの範囲を超えています。XcodeフレームワークデバッガーとツールはAppleプラットフォームでのIL2CPPビルドにのみ使用できるため、現在はIOSビルドの構成にのみ使用できることに注意してください。

Unityプロファイラー

UnityProfilerの主な目的は、比較分析を実行することです。UnityProfilerの実行中にUI要素を有効または無効にすると、パフォーマンスの問題に最も関与するUI階層の部分をすばやく絞り込むことができます。

これを分析するには、アナライザー出力のCanvas.BuildBatchとCanvas.endWillRenderCanvasesの行を確認します。

前述のように、Canvas.BuildBatchは、キャンバスバッチ生成プロセスを実行するネイティブコード計算です。

Canvas.SendWillRenderCanvasesには、サブスクライブされたCanvasコンポーネントのWillRenderCanvasesイベントを呼び出すC#スクリプトが含まれています。UnityUIsCanvasUpdateRegistryクラスはこのイベントを受け取り、前述のようにそれを使用して再構築プロセスを実行します。ダーティなUIコンポーネントは、現時点で「キャンバスレンダラー」を更新することが予想されます。

注:UIパフォーマンスの違いを簡単に確認できるように、通常は、「レンダリング」、「スクリプト」、「UI」を除くすべてのトラッキングカテゴリを無効にすることをお勧めします。これは、CPU使用率アナライザーの左側にある追跡カテゴリー名の横にある色付きのボックスをクリックすることで実行できます。カテゴリ名をクリックして上下にドラッグすることにより、CPUアナライザでカテゴリを並べ替えることもできます。

UIカテゴリは、Unity2017.1以降で新しく追加されました。残念ながら、UI更新プロセスの一部は適切に分類されていないため、UI曲線を見るときは注意してください。これには、UI関連の呼び出しがすべて含まれているとは限りません。たとえば、Canvas.endWillRenderCanvasesは「UI」に分類され、Canvas.BuildBatchは「その他」と「レンダリング」に分類されます。

2017.1以降では、新しいユーザーインターフェイスアナライザーもあります。デフォルトでは、このプロファイラーはプロファイラーウィンドウの最後のプロファイラーです。これは、2つのタイムテーブルとバッチビューアで構成されています。

最初のタイムラインは、計算レイアウトと表示という2つのカテゴリに使用されるCPU時間を示しています。前述と同じ問題が発生し、一部のUI機能が説明されていない場合があることに注意してください。

2番目のタイムラインには、バッチ、頂点、およびイベントマーカーの総数が表示されます。前のスクリーンショットでは、いくつかのボタンクリックイベントを見ることができます。これらのマーカーは、CPUスパイクの原因を特定するのに役立ちます。

最後に、UIProfilerの最も便利な機能は、下部にあるバッチビューアです。左側には、すべてのキャンバスのツリービューがあり、各キャンバスの下には、それらが生成するバッチのリストがあります。これらの列は、各キャンバスまたはバッチに関する興味深い詳細を提供しますが、UIを最適化する方法をよりよく理解するには、そのうちの1つが重要であるため、バッチが中断されます。

この列には、選択したバッチを前のバッチとマージできない理由が表示されます。バッチの数を減らすことは、UIのパフォーマンスを向上させる最も効果的な方法の1つであるため、バッチを中断する可能性があるものを理解することが重要です。

スクリーンショットに示されているように、最も一般的な理由の1つは、さまざまなテクスチャまたはマテリアルを持つUI要素の使用です。多くの場合、これはスプライトアトラスを使用することで簡単に解決できます最後の列は、バッチに関連付けられているゲームオブジェクトの名前を示しています。名前をダブルクリックして、エディターでゲームオブジェクトを選択できます(これは、同じ名前のオブジェクトが複数ある場合に特に便利です)。

Unity 2017.3以降、バッチビューアーはエディターでのみ機能します。デバイスでは、バッチ処理は通常同じである必要があるため、これは依然として非常に便利です。デバイスでのバッチ処理が異なる可能性があると思われる場合は、次に説明するフレームワークデバッガーを使用できます。

Unityフレームデバッガー

UnityFrameworkDebuggerは、UnityUIによって生成される描画呼び出しの数を減らすための便利なツールです。この組み込みツールには、Unityエディターのウィンドウメニューからアクセスできます。有効にすると、UnityUIによって生成された呼び出しを含め、Unityによって生成されたすべての描画呼び出しが表示されます。

フレームワークデバッガーは、生成された描画呼び出しで自身を更新して「Unityエディター」に「ゲームビュー」を表示するため、「プレイモード」に入らずにさまざまなUI構成を試すことができます。

UnityUIの描画呼び出しの場所は、描画されるキャンバスコンポーネントで選択されたレンダリングモードによって異なります。

  • 画面スペース- オーバーレイはCanvas.RenderOverlayグループに表示されます。
  • 画面スペース-カメラは、RenderのサブグループとしてCamer.Renderグループに表示されます。
  • World Spaceは、Renderのサブグループとして表示されます。表示されている各キャンバスのワールドスペースカメラの透明なジオメトリ

すべてのUIは、「シェーダー:UI /デフォルト」行で識別できます(UIシェーダーがカスタムシェーダーに置き換えられていないことを前提としています)。グループまたは宝くじの電話の詳細。以下のスクリーンショットで強調表示されている赤いボックスを参照してください。

UIを調整しながらこの行のセットを表示することにより、UI要素をバッチに結合するキャンバスの機能を最大化するのは比較的簡単です。設計関連の壊れたバッチの最も一般的な原因は、意図しない重複です。

すべてのUnityUIコンポーネントは、一連のクォータニオンとしてジオメトリを生成します。ただし、多くのUIスプライトまたはUIテキストシンボルは、それらを表すためにクォータニオンファイルのごく一部しか占めておらず、残りはスペースです。そのため、UIデザイナーが誤って複数の異なる四角形を重ねてしまい、それらのテクスチャが異なる素材からのものであるため、バッチで処理できないことがよくあります。

UnityUIは完全に透過キューで動作するため、その上にオーバーレイされた不安定な四角形は、壊れないクォータニオンの前に描画する必要があります。したがって、壊れないクォータニオンに配置された他の四角形とバッチ処理することはできません。

A、B、Cの3つの四角形の場合を考えてみましょう。これらの3つの四角形が互いに重なり合っていると仮定し、四角形AとCが同じ材料を使用し、クォータニオンBが別の材料を使用していると仮定します。したがって、バッチAまたはCをクワッドBに使用することはできません。

階層内の順序(上から下)がA、B、Cの場合、BはAの上、Cの下に描画する必要があるため、AとCをバッチ処理することはできません。ただし、Bがバッチ可能クォータニオンの前または後に配置されている場合、バッチ可能クォータニオンはバッチ処理できます。Bは、バッチ処理されたクォータニオンの前または後に描画するだけでよく、挿入されません。

この問題についてさらに説明するには、Canvasの章の子の順序のセクションを参照してください

楽器とVTune

XcodeのInstrumentsとIntelのVTuneにより、それぞれAppleまたはIntelCPUでのUnityUIの再構築とCanvasバッチ計算の非常に詳細なプロファイリングが可能になります。メソッド名は、上記のUnityプロファイラーセクションで説明したプロファイラーラベルとほぼ同じです。

  • Canvas :: SendWillRenderCanvasesは、Canvas.SendWillRenderCanvases C#メソッドを呼び出し、Unityプロファイラーでその行を管理するC ++の親です前の章で説明したように、再構築プロセスの実行に使用されるコードが含まれます

  • Canvas :: UpdateBatchesCanvas.BuildBatchと同じですが、UnityProfilerラベルでカバーされていない追加の定型コードが含まれています。上記の実際のCanvasBatchBuildingプロセスを実行します。

IL2CPPを介して構築されたUnityアプリと組み合わせて使用​​すると、これらのツールを使用して、Canvas :: SendWillRenderCanvasesのトランスパイルされたC#コードをさらに深く掘り下げることができます。主な関心事は、以下の方法のコストです。(注:トランスパイルされたメソッド名は概算です。)

  • IndexedSet_SortおよびCanvasUpdateRegistry_SortLayoutListは、レイアウトが再計算される前に、ダーティなレイアウトコンポーネントのリストを並べ替えるために使用されます。上記のように、これには、各レイアウトコンポーネントの上の親変換の数の計算が含まれます。
  • ClipperRegistry_Cullは、IClipRegionインターフェイスの登録済み実装者すべてを呼び出します。組み込み実装含むRectMask2D IClippableインターフェースを使用し、。ClipperRegistry.Cullの呼び出し中にRectMask2Dコンポーネントは、階層内に含まれるすべてのクリップ可能な要素をループし、カリング情報を更新するように要求します。
  • Graphic_Rebuildには、画像、テキスト、またはその他のグラフィックから派生したコンポーネントを表すために必要なメッシュを実際に計算するコストが含まれます。これはのようないくつかの他の方法になります下にGraphic_UpdateGeometryと、最も顕著なのは、Text_OnPopulateMesh
    • Text_OnPopulateMeshは通常、ベストフィットが有効になっている場合のホットスポットです。これについては、このガイドの後半で詳しく説明します。
    • Shadow_ModifyMeshOutline_ModifyMeshなどのメッシュ修飾子もここで実行されます。コンポーネントのドロップシャドウ、アウトライン、およびその他の特殊効果を計算するコストは、これらの方法で確認できます。

XcodeフレームデバッガーとIntelGPA

低レベルのフレームデバッグツールは、バッチ処理されたUIの個々の部分のコストをプロファイリングし、UIのオーバードローのコストを監視するために不可欠です。UIのオーバードローについては、このガイドの後半で詳しく説明します。

Xcodeフレームデバッガーの使用

特定のUIがGPUに過度の負荷をかけているかどうかをテストするには、Xcodeの組み込みGPU診断ツールを使用できます。まず、MetalまたはOpenGLES3を使用するように問題のプロジェクトを構成してから、ビルドを作成して、結果のXcodeプロジェクトを開きます。一部のXcodeバージョンとデバイスの組み合わせは、OpenGLES 2フレームキャプチャをサポートしている場合がありますが、それが機能するという保証はありません

注: Xcodeの一部のバージョンでは、グラフィックスプロファイラーを機能させるために、ビルドスキームで適切なグラフィックスAPIを選択する必要があります。これを行うには、Xcodeの[製品]メニューに移動し、[スキーム]メニュー項目を展開して、[スキームの編集...]を選択します。[実行]ターゲットを選択し、[オプション]タブに移動します。プロジェクトで使用されるAPIに一致するように、GPUフレームキャプチャオプションを変更します。UnityプロジェクトがグラフィックAPIを自動的に選択するように設定されているとすると、最近のほとんどのiPadはデフォルトでMetalを使用します。疑わしい場合は、プロジェクトを開始し、Xcodeのデバッグログを確認してください。初期の行の1つは、どのレンダリングパス(Metal、GLES3、またはGLES2)が初期化されているかを示している必要があります。

iOSデバイスでプロジェクトをビルドして実行します。GPUプロファイラーは、Xcodeのナビゲーターサイドバーに[デバッグ]ペインを表示し、FPSエントリをクリックすると表示されます。

GPUプロファイラーの最初の注目点は、画面の中央にある「タイラー」、「レンダラー」、「デバイス」というラベルの付いた3本のバーのセットです。これら2つのうち:

  • 「タイラー」は通常、ジオメトリの処理によるGPUのストレスの尺度であり、頂点シェーダーで費やされた時間を含みます。一般に、「タイラー」の使用率が高い場合は、頂点シェーダーが遅すぎるか、描画される頂点の数が多すぎることを示します。
  • 「レンダラー」は通常、GPUのピクセルパイプラインにかかるストレスの尺度です。一般に、「レンダラー」の使用率が高い場合は、アプリケーションがGPUの最大フィルレートを超えているか、フラグメントシェーダーが非効率的であることを示しています。
  • 「デバイス」は、「タイラー」と「レンダラー」の両方のパフォーマンスを含む、GPU全体の使用量の複合的な尺度です。「タイラー」または「レンダラー」の測定値の高い方を大まかに追跡するため、通常は無視できます。

XcodeのGPUプロファイラーの詳細については、このドキュメントの記事を参照してください

Xcodeのフレームデバッガーは、GPUプロファイラーの下部に隠されている小さな「カメラ」アイコンをクリックすることでトリガーできます。次のスクリーンショットでは、矢印と赤いボックスで強調表示されています。

少し間を置くと、次のようにフレームデバッガの概要ビューが表示されます。

デフォルトのUIシェーダーを使用する場合、デフォルトのUIシェーダーがカスタムシェーダーに置き換えられていないと仮定すると、UnityUIシステムによって生成されたジオメトリのレンダリングのコストは「UI /デフォルト」シェーダーパスの下に表示されます。上のスクリーンショットでは、このデフォルトのUIシェーダーがレンダリングパイプライン「UI /デフォルト」として表示されている可能性があります

Unity UIはクワッドのみを生成するため、頂点シェーダーがGPUのタイラーパイプラインにストレスを与える可能性はほとんどありません。このシェーダーパスに表示される問題は、フィルレートの問題が原因である可能性があります。

プロファイラーの結果の分析

プロファイリングデータを収集した後、いくつかの結論が導き出される可能性があります。場合Canvas.BuildBatchまたはキャンバス:: UpdateBatchesは、 CPU時間を使いすぎているように見える、そして可能性の高い問題は、単一のキャンバスキャンバスレンダラコンポーネントの過剰な数です。キャンバスのの「キャンバスの分割」セクションを参照してください

GPUでUIを描画するのに過度の時間が費やされ、フレームデバッガーがフラグメントシェーダーパイプラインがボトルネックであることを示している場合、UIはGPUが可能なピクセル充填率を超えている可能性があります。最も可能性の高い原因は、過度のUIオーバードローです。フィルレート、キャンバス、および入力のの「フィルレートの問題の修正セクションを参照してください

Canvas.SendWillRenderCanvasesまたはCanvas :: SendWillRenderCanvases行くCPU時間の大部分に見られるように、グラフィックリビルドが過剰なCPUを使用している場合は、より詳細な分析が必要です。グラフィック再構築プロセスの一部が原因である可能性があります。

大部分た場合にWillRenderCanvasが内部費やされIndexedSet_Sort又はCanvasUpdateRegistry_SortLayoutList、その後時間が汚れレイアウト・コンポーネントのリストをソートする費やされています。Canvas上のレイアウトコンポーネントの数を減らすことを検討してください。可能な修正方法については、「レイアウトをRectTransformsに置き換える」およびキャンバス分割する」セクションを参照してください

Text_OnPopulateMesh過度の時間が費やされていると思われる場合、原因は単にテキストメッシュの生成です。考えられる修正方法については、「ベストフィット」およびキャンバスの無効化」セクションを参照してください。再構築されるテキストの多くが実際に基になる文字列データを変更していない場合は、「キャンバスの分割」内のアドバイスを検討してください。

Shadow_ModifyMeshまたはOutline_ModifyMeshまたはModifyMeshの他の実装内で時間が費やされている場合、問題はメッシュモディファイヤの計算に過度の時間が費やされていることです。これらのコンポーネントを削除し、静止画像を介して視覚効果を実現することを検討してください。

Canvas.SendWillRenderCanvases内に特定のホットスポットがない場合、またはすべてのフレームで実行されているように見える場合は、動的要素が静的要素と一緒にグループ化されており、Canvas全体の再構築が頻繁に行われている可能性があります。キャンバス分割のセクションを参照してください

おすすめ

転載: blog.csdn.net/Momo_Da/article/details/93532474