[UE4] Widget Reflectorを使ってリソースや設定を調べよう

#1. 概要
Widget ReflectorはWidget関連のデバッグに有効なツールの１つで、様々な機能を備えており、

・現在表示に利用しているWidget, Slateの設定やリソースの情報を見ることができる
・Widgetの設定を見ることでパフォーマンス解析や最適化が適用されているかなどに活用できる
・これを利用してSlate実装を逆引きして参考にする時にも役に立つ
・Font Atlases, Texture Atlasesの機能を利用してロードされたリソースを確認できる

など、色々な用途に利用することができます。
![2019-11-29_02h34_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/2200e24d-64cb-e73a-b6c4-716bda26f20e.png)

#2. 使い方
##2.1. クイックスタート
[Window]->[Developer Tools]->[Widget Reflector]を選択します。
![2019-11-29_02h25_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/51e6d725-8c4e-f71d-afa8-e88eec9be3c5.png)

もしくは、コンソールコマンドで"WidgetReflector"と入力します。
![2019-11-14_14h53_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/a6d37ee2-b6bf-cc9c-f64d-0f2d7eb78491.png)

ウィンドウが開いたら[Pick Hit-Testable Widgets]を選択してリアルタイムキャプチャを行います。
![2019-11-14_15h03_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/1dd23703-b2fb-633c-0c63-cb5d4a9999f0.png)

[Picking(Esc to Stop)]を選択するか、Escキーを押してキャプチャ終了します。
![2019-11-29_10h56_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/173f469e-c2a3-62b6-35d3-d0d01ce8300f.png)

キャプチャできると上記のような図を表示できます。選択したWidgetがプロジェクトのアセットの場合、リソースやスロットの各設定なども表示することができます。

#3. 機能

##3.1. GUI詳細
　Widget ReflectorのGUI及び、各パラメータの内容は以下の通りです。
(ソースファイル:SWidgetReflector.cpp, SWidgetReflectorTreeWidgetItem.cpp, WidgetReflectorNode.cpp参照)

###3.1.1. Widget Reflector
![2019-11-29_02h36_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/b9c20634-08e2-614d-658d-aebec0be4c78.png)

|項目				|説明											|
|:---				|:---											|
|Application Scale		|アプリケーションスケールバー<br>アプリケーション全体のSlateに対するスケール値の指定(0.5～3.0)	|
|Widget Caching			|キャッシュボタン<br>Widgetをキャッシングしている状態の表示					|
|Invalidation Debugging		|Invalidationデバッグボタン<br>Invalidation Boxなどによるキャッシュ関連のデバッグ表示	|
|Demo Mode			|デモモード切替ボタン<br>マウスクリック時にクリックのフィードバックアクションを表示		|
|Display Texture Atlases	|テクスチャアトラス表示ボタン<br>テクスチャアトラス用ウィンドウの表示				|
|Display Font Atlases		|フォントアトラス表示ボタン<br>フォントアトラス用ウィンドウの表示				|

###3.1.2. Widget Hierarchy
![2019-11-29_02h36_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/72b643ab-d0db-c259-009b-0d679aa1c116.png)

|項目				|説明					|
|:---				|:---					|
|Show Focus			|フォーカス表示ボックス<br>フォーカスしているSlateを緑色の枠で強調する		|
|Pick Hit-Testable Widgets	|Widget選択ボタン(判定)<br>押下するとWidget選択モード時に移行<br>HitTestが可能なWidgetを選択して詳細が確認可能	|
|Pick Painted Widgets		|Widget選択ボタン(描画)<br>押下するとWidget選択モード時に移行<br>描画が許可されたWidgetを選択して詳細が確認可能|
|Take Snapshot			|スナップショット撮影ボタン<br>表示中の全てのウィンドウ情報をキャプチャしてスナップショットとして選択可能とする	|
|Delay				|スナップショット撮影前遅延ボックス(s)<br>上記のスナップショットキャプチャ撮影前に指定時間のディレイを設ける	|
|Snapshot Target		|スナップショット対象ボックス<br>スナップショット撮影の対象となるPCを指定する					|
|Load Snapshot			|スナップショットロードボタン<br>保存済みのスナップショットファイル(.widgetsnapshot)を読み込んで展開する	|


###3.1.3. Widget Tree
![2019-11-29_02h36_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/001c1251-481a-7fed-7f7f-72b6d6734652.png)
　キャプチャした表示は以下のような内容となっています。

|項目		|説明										|
|:---		|:---										|
|Widget Name	|Widget名<br>Widgetの階層構造をリストで表示					|
|FG		|Foreground Color<br>前面色の状態を表示						|
|Visibility	|可視性<br>可視性の状態を表示							|
|Focus?		|フォーカス可否<br>IsFocusableの設定に応じてチェックあり/なしを表示			|
|Clipping	|Clipping状態<br>Clipping設定に応じてNo/Yes/Yes(Always)/Yes(NoIntersect)/OnDemandを表示		|
|Source		|ソースファイル<br>使用しているWidget/Slate表示<br>選択するとアセットやコードにジャンプ		|
|Address	|アドレス<br>使用中のSWidgetのポインタアドレスを表示						|


##3.2. 機能詳細
###3.2.1. Widget Hierarchy表示
　Widget及びSlateの構成を階層構造で表示することができます。これにより現在のUI表示がどのような構成から成り立っているものか、現在表示中のWidgetに対して正しい設定が適用されているか、といった内容を確認することができます。Sourceの部分をクリックすると、Widgetが選択されている場合は対象アセットを開き、C++がコードである場合は対象コードが追加される箇所までジャンプします。
![2019-11-29_16h42_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/76081bd2-822d-aa0c-b5d0-bd419439e638.png)

###3.2.2. Live Widget編集
　Widget Hierarchyの中でWidgetアセットを選択していた場合、Widget Detailsタブには選択中のWidgetComponentの情報を表示することができます。これらの設定はPreview中に編集することで値を一時的に変更したり試すことができます。ここでの変更内容はアセットに直接反映されませんが、ここで編集出来ることでSlateやパフォーマンスの変化などを即時変更して確認したり、リソースの差し替えと確認が出来ます。
![2019-11-29_16h20_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/2296f0e3-cf54-a917-793f-da075535c6b8.png)

###3.2.3. Invalidation Debugging
　[「Invalidiation Box」](https://docs.unrealengine.com/ja/Engine/UMG/UserGuide/WidgetTypeReference/Invalidation/index.html)でも説明されているように、UMGを利用したUIの構築において、Invalidation Boxを使ったキャッシングはパフォーマンスの面で有効です。以下、デバッグモード表示時の各画面への影響と説明です。このデバッグモードを利用することで、正しくキャッシュが適用出来ているか等を確認しておくこともできます。

**1) 4.20での表示**
![2019-11-29_10h45_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/a9dffbfa-91d6-8248-273d-01ab2bbfb4fa.png)

|項目	|説明							|
|:---	|:---							|
|緑線	|**Invalidation Boxを適用するWidget**<br>Invalidation Boxによる最適化が適用されているかを確認でき、この表示が無い場合は全く適用されていない可能性があります	|
|青線	|**Cache Relative Transformsを伴うInvalidation Box**<br> bCacheRelativeTransformのチェックが有効なことを示します		|
|赤線	|**Invalidation Boxが無効なWidget**<br>Cacheが有効にも関わらずレイアウトの更新が発生してキャッシュされないことを示します	|
|黄破線	|**VolatileとしてチェックされたWidget**<br>レイアウトの更新などを意図的に起こす場合などCacheされないことを明示的に示して、キャッシュするためのコストを制約します	|

[Note]
赤はInvalidation Boxを配置した子Widgetで意図的にRenderScaleを変更させたものです。

**2) 4.24での表示**

![2020-02-12_20h49_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/c08d7cc0-2be7-dd81-46e7-e7c84b2ec54e.png)

|項目	|説明							|
|:---	|:---							|
|紫破線	|**Invalidation BoxのCacheがON**	|
|線なし	|**Invalidation BoxのCacheがOFF** 	|

[Note]
4.24ではInvalidation Boxの適用有無のみを表示します。

###3.2.4. Texture Atlases
　アトラス化されたテクスチャを一覧で表示します。表示するテクスチャはFSlateRHIResourceManager::TextureAtlasesを参照します。ここでは使用中のテクスチャアトラスを表示していますが、EditorとStandaloneではロードされるリソースに差分があるため(Editorでは全てが起動時にロードされる)、もしPCで確認する場合はStandalone起動において確認されることをお勧めします。

![2019-11-29_10h57_28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/a56e2ad0-2f16-b96a-8531-c77888815c58.png)

###3.2.5. Font Atlases
　アトラス化されたフォントを一覧で表示します。表示するテクスチャはFSlateFontCache::TextureAtlasesを参照します。ここでは使用中のフォントアトラスを表示していますが、EditorとStandaloneではロードされるリソースに差分があるため(Editorでは全てが起動時にロードされる)、もしPCで確認する場合はStandalone起動において確認されることをお勧めします。

![2019-11-29_10h57_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/b6743c8f-58b8-ef11-6627-be7da606a62a.png)

###3.2.6. Snapshot
　EditorでWidgetの階層構造をキャッシュして、その値を確認したり変更できるということを上記で述べましたが、その階層構造の情報をSlate込みでSnapshotとして保存することが出来ます。以下の図はPIEで動作させているプロジェクトのSnapshotを撮影したばかりのものです。Snapshotをロードし直すことでSlateの状態を復元したり、再現することが可能となります。

![2019-11-29_12h18_00-min.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/2eb49997-9c53-bf46-1733-9ecb965af22d.gif)

#4. まとめ
Widget Reflectorを利用することで、各Widgetの設定をランタイムで確認できたり、どのリソースが参照されているかを簡単に特定することができます。これらをうまく活用してデバッグを効率的に行いましょう。