[UE4] Collision Analyzerで見えない負荷を探そう

#1. 概要
　Collision Analyzerはコリジョンや物理イベントを特定することができるツールの１つです。

![2019-11-25_14h48_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/f818cfa5-4622-ed06-f6e1-5bf7972576d7.png)


例えば、以下のようなものを調べるのに有用です。

・処理負荷のポイントはどこか？
・発生源は誰か？
・どんな種類のコリジョン／物理処理が発生しているか？
・1フレーム中にどの程度のコリジョンイベントが発生しているか？

この記事ではこのCollision Analyzerを使って出来ることや、プロジェクトでの活かし方を説明します。

#2. 使い方
　Collision Analyzerは[Window]->[Developer Tools]->[Collision Analyzer]から開くことができます。
![2019-11-29_02h58_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/3991d1df-962a-c1b9-7c5c-1b59a38e51f0.png)

　録画ボタンを押すと、シーン中のコリジョンイベントをキャプチャ開始します。
![2019-11-25_15h15_011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/0e0963b9-7023-9c9a-031d-3548b0d5e24e.png)

　キャプチャしたデータからどのような形状でイベントが発生していたかを確認できます。以下は「キャラクターが移動する際に発生する、進行方向にCapsuleのSweep処理」が発生している図です。白色のデバッグラインでSweepの軌跡を表示しています。
![2019-11-14_12h32_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/82f35552-d31b-d098-aa77-bd40e4e98952.png)


#3. 機能
　Collision AnalyzerのUI及び、各パラメータの内容は以下の通りです。
(ソースファイル:SCollisionAnalyzer.cpp, SCAQueryTableRow.cpp, SCAQueryDetails.cpp参照)

![2019-11-25_15h15_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/72f180a2-26b6-145b-1e9b-95a7290f0cd1.png)

**ボタンの説明**
![2019-11-25_15h42_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/04857031-f833-44cc-0d87-35f84cceb65d.png)

|ボタン		|説明							|
|:--------------|:------------------					|
|Record		|録画/停止ボタン<br>キャプチャを開始、再押下で停止		|
|Draw Recent	|描画ボタン<br>最新のコリジョンデータを画面上に表示		|
|Open		|開くボタン<br>過去にキャプチャしたデータを開く		|
|Save		|保存ボタン<br>現在キャプチャしたデータを.uca形式で保存	|

**Query関連の説明**
![2019-11-25_15h42_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/ba594f8c-91a0-971b-a1b4-c886740a01ac.png)

|項目		|説明						|
|:--------------|:------------------				|
|ID		|一意の番号					|
|Frame		|キャプチャ開始からのフレーム数<br>同一フレームで発生したイベントは同一Frame番号を表示			|
|Type		|どのような種類のコリジョンイベントが発生したか<br>Raycast/Sweep/Overlap/Unknownを表示		|
|Shape		|どのような形状のコリジョンイベントが発生したか<br>Sphere/Box/Capsule/Convex/Unknownを表示		|
|Mode		|どのような判定が発生したか<br>Test/Single/Multi/Unknownを表示					|
|Tag		|どのようなイベントが発生したか<br>FCollisionQueryParams::TraceTagを表示		|
|Owner		|誰がコリジョンイベントを発生させたか<br>FCollisionQueryParams::OwnerTagを表示		|
|#B		|ブロッキングが何回発生したか<br>全FHitResult::bBlockingHit=Trueの数を表示<br>FHitResult::bStartPenetrating=Trueの場合は赤色表示|
|#T		|オーバーラップが何回発生したか<br>全ヒット数－全ブロッキングヒット数を表示			|
|ms		|CPU処理に掛かった時間									|

**HitResult関連の説明**
![2019-11-25_15h44_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/eb69a226-a393-4c39-aef4-b780a509df3a.png)

|項目		|説明								|
|:--------------|:------------------						|
|Start		|ヒットテスト開始位置						|
|End		|ヒットテスト終了位置						|
|Show Misses	|未検出イベント情報の表示フラグ					|
|Time		|検出時の処理時間(ms)を表示<br>FHitResult::Timeを表示		|
|Type		|検出時のコリジョンタイプを表示<br>Miss/Block/Touchを表示		|
|Component	|検出時の対象コンポーネントを表示<br>Invalid/対象Component名を表示	|
|Normal		|検出時の法線情報を表示<br>FHitResult::Normalを表示		|

　貫通が発生した場合は図のように赤色でそのイベントデータを表示します。

![2019-11-28_22h57_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/4da69c78-14ef-7637-5b74-9336ca49134e.png)

　"Show Misses"はミスが発生したコリジョンイベントの表示用フラグで、有効な場合は図のように薄紫色でそのイベントデータを表示します。

![2019-11-28_22h57_51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/60d073eb-8973-78ca-b867-9b2fdf52a479.png)


#4. プロジェクトで活用
　Engine側で提供された機能については、Collision Analyzerで解析する際に原因特定が容易なように予めTagやOwnerの情報が設定されているケースがあります。プロジェクトでも同様にコリジョンやトレースといったイベントを適用する際には、Analyzerに出力するためにTagやOwnerの情報を埋め込んでおくと便利です。これらの情報、上記のリストにもあるように「FCollisionQueryParams」を参照して、プロジェクトで独自のタグを追加することもできます。以下はCharacterMovementでの一例です。

```cpp:CharacterMovementComponent.cpp
	FCollisionQueryParams QueryParams(SCENE_QUERY_STAT(ComputeFloorDist), false, CharacterOwner);
	FCollisionResponseParams ResponseParam;
	InitCollisionParams(QueryParams, ResponseParam);
```

#5. プロファイルで活用
　コリジョンアナライザーでキャプチャできる結果はコリジョンに関するイベントであるため、ビルド構成やターゲットプラットフォームに殆ど依存しません。よってPIEでも同じようなキャプチャデータを取得することができます。もしCPU負荷が高そう、コリジョンやトレースに負荷が影響していそうな場合、PIEでキャプチャを取って解析してみても十分なキャプチャデータが得られるはずです。以下はキャプチャデータから推測される事象や、得られる結果から想定される事象を記載してみました。このような観点で見たとき、キャプチャしたシーンのコリジョンイベントが想定された通りに動作しているかどうかを疑って見てみることをお勧めします。

![2019-11-28_17h46_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/b68644d3-4bbd-65cc-0253-4cb1009af271.png)


#6. まとめ
Collision Analyzerを利用することで、視認による特定が難しいCollision Eventの特定ができ、CPU負荷削減調査などに役立ちます。これらをうまく活用してデバッグを効率的に行いましょう。