確認したバージョンは UE4.27.2 です。
参考URL
- 猫でも分かるUMG - Slideshare
- UE4で作成するUIと最適化手法 - Slideshare
- コンソール スレート デバッガ - UE4公式ドキュメント
- ウィジット リフレクタ - UE4公式ドキュメント
- Slate Insights の概要 - UE4公式ドキュメント
Retainer Box とは?
- 更新頻度が低くても構わないウィジットに有効。
- 子ウィジットをテクスチャレンダリングして、そのテクスチャを表示する。
- 更新頻度が低くてよいときなどに使用する。
- なので、毎フレームレンダリングさせてしまうと逆に重くなる。
参考URL
- 猫でも分かるUMG - Slideshare の115ページ目
- UE4で作成するUIと最適化手法 の127ページ目
Render on Phase
一定周期でレンダリングする。
(上のスクショならば、30フレームに1回)
Phaseを変えると、その30フレームに1回のうちの何フレーム目にレンダリングするかを指定できる。
- 【一番左】Retainer Box を使わない普通の状態。
- 【左から2番目】Retainer Boxで毎フレームレンダリングしたもの (重い)
- 【左から3番目】Retainer Boxで30フレームに一回レンダリングしたもの
- 30フレーム周期の0番目のタイミングでレンダリング
- 【左から4番目】Retainer Boxで30フレームに一回レンダリングしたもの
- 30フレーム周期の15番目のタイミングでレンダリング
Render on Invalidation
- 内容に変更があればレンダリングする。(サイズやレイアウトの変更など)
- RequestRender ノードを使えば、任意タイミングでレンダリングを行える。
ボタンを押すたびレンダリングする例:
本題。いつ更新されたかをデバッグ表示したい
コンソール スレート デバッガを使う。
…のだが、公式のリファレンスを見てもなんだか良く分からない。
以下は、結局ソースを追いかけて分かったことのメモ。
Retainer Boxの更新タイミングをデバッグ表示するコンソールコマンドは:
SlateDebugger.InvalidationRoot.Start
(これを終了するにはSlateDebugger.InvaidationRoot.Stop
)
デバッグ表示色 | 意味 |
---|---|
赤 | Slow Path (レンダーテクスチャのリサイズ(再確保)が必要な場合) |
緑 | Fast Path (レンダーテクスチャのサイズ変更が不要な場合) |
青 | None (何も更新していない) |
2021/12/23 Slow Path, Fast Path の説明文を修正しました。
誤 Slow Path (レンダリングを行っている)
正 Slow Path (レンダーテクスチャのリサイズ(再確保)が必要な場合)
誤 Fast Path (どうやらInvalidation Boxで使っているようだ…たぶん)
正 Fast Path (レンダーテクスチャのサイズ変更が不要な場合)
以下のような絵になる:
問題は、すべてのRetainer Boxが、終始「赤」で表示されている点である。
「こんなハズではない!」と変な汗をかいてしまう。
ソースを追いかけて知ったのだが FConsoleSlateDebuggerInvalidationRoot
クラスにはCacheDuration
なる秒数を保持する変数があり、Slow Path/Fast Path/None が変わった後「CacheDuration」秒だけかけて色をゆっくりと変えているようだ(lerp)。
で、このデフォルト値が2.0秒。
つまり、30フレームに1回程度の更新では、lerpが追いつかず、ひたすら赤のままになるわけである。
何という罠。
というわけで、CacheDuration を任意に変更したい
私のWeb検索力では、このことについて言及した記事を見つけることができなかった。
ソースを調べると、以下の.iniファイルを書き換えることで可能だと分かった:
<プロジェクトDir>/Saved/Config/Windows/EditorPerProjectUserSettings.ini
このファイルにはかなりたくさんの項目があるが、その中の[SlateDebugger.InvalidationRoot]
を探す。(ないなら手動で追加する)
[SlateDebugger.InvalidationRoot]
bDisplayInvalidationRootList=True
bUseWidgetPathAsName=False
bShowQuad=True
DrawSlowPathColor=(R=255,G=0,B=0,A=255)
DrawFastPathColor=(R=0,G=255,B=0,A=255)
DrawNoneColor=(R=0,G=0,B=255,A=255)
MaxNumberOfWidgetInList=20
CacheDuration=2.000000
最後のCacheDuration
を任意の秒数 (例: 0.15 秒) に変更するとこうなる:
Render on Phase版
Phase Count = 30の2つは Phase = 0 と 15 の異なるタイミングで更新されているのが分かる。
Render on Invalidation版
ボタンを押して RequestRender を呼び出したときだけ更新されているのが分かる。
関連するエンジンソース
-
class URetainerBox
: Retainer Boxウィジット。 -
class SRetainerWidget
: Retainer Boxウィジットが持っている Slate。これが本体。 -
class FSlateInvalidationRoot
: Retainer Box, Invalidation Boxの基底クラス。- これが更新の可否(Fast Path, Slow Path, None)を決めている。
- Fast Path, Slow Path, None は、このクラス宣言の少し上に
enum class ESlateInvalidationPaintType
として宣言されている。
-
class FConsoleSlateDebuggerInvalidationRoot
: コンソール スレート デバッガの InvalidationRoot の機能。
雑記
- Widget Reflector はコンソールスレートデバッガの機能を呼び出しているようだ。
- Slate Insights は公式ドキュメントの通りにやれば使える。
- だが、ズーム機能がうまく働かなくて、個々のフレームの状態を選択するには、非常に微妙なマウス操作を要する。改善してほしいなぁ。