UE4で作成するUIと最適化手法 【GAME CREATORS CONFERENCE '20】

314K Views

June 10, 20

スライド概要

2020年6月10日に公開された「GAME CREATORS CONFERENCE '20」の動画配信で使用した資料です。

・公式HP
http://www.gc-conf.com/
・Youtube動画ページ
https://www.youtube.com/watch?v=x67C_RqRVrg

profile-image

Unreal Engineを開発・提供しているエピック ゲームズ ジャパンによる公式アカウントです。 勉強会や配信などで行った講演資料を公開しています。 公式サイトはこちら https://www.unrealengine.com/ja/

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

UE4で作成するUIと最適化手法 Epic Games Japan Software Engineer, Developer Relations 鍬農 健二郎 #UE4 | #gcconf2020

2.

何故UIをやるのか? #UE4 | #gcconf2020

3.

概要 ● 目的 ● UMGを使って効率的にUIを構築できる ● UIの最適化方法を適用できる ● 対象 ● UMGを利用するアーティスト ● 実装や最適化をするエンジニア、TA ● 適用範囲 UE 4.25 #UE4 | #gcconf2020

4.

本日のお題 設計 仕組み #UE4 | #gcconf2020 最適化

5.

本日のお題 ● 設計 ● レイアウト設計 ● クラス設計 … アート … エンジニア ● 仕組み ● ライフサイクル … エンジニア ● 最適化 ● オプション ● デバッグ #UE4 | #gcconf2020 … アート、エンジニア … アート、エンジニア

6.

https://www.slideshare.net/EpicGamesJapan/umg-80334310 UMGを基礎から学びたい方はコチラがおすすめ #UE4 | #gcconf2020

7.

目次 ● 設計 ● レイアウト設計 ● クラス設計 ● 仕組み ● 最適化 #UE4 | #gcconf2020

8.

レイアウト設計 #UE4 | #gcconf2020

9.

レイアウト設計は悩む 再利用 見栄え 無駄なく #UE4 | #gcconf2020

10.

おさらい ● Widget 小さな機能単位の表示要素 ● User Widget Widgetを組み合わせて作成する表示要素 ⇒ Main Widget, Sub Widget #UE4 | #gcconf2020

11.

Widget Sub Widget Widget #UE4 | #gcconf2020

12.

User Widget レイアウト Main Widget #UE4 | #gcconf2020 ボタンセット アタックボタン Sub Widget

13.

レイアウト設計での課題 ● ● ● ● ウィジェットを配置する基準は? ウィジェットの使い分け方は? ウィジェットを再利用する方法は? アニメーションを再利用する方法は? #UE4 | #gcconf2020

14.

課題1:ウィジェットを配置する基準は? ● ウィジェットを配置する理由を意識する 何故それを使ったか説明できるように配置する ● レイアウトが常に変わることを意識する レイアウト変更、マルチプラットフォームに対応 #UE4 | #gcconf2020

15.

Widgetの配置例 #UE4 | #gcconf2020

16.

Widgetの配置例 複数の子Widgetをレイヤー管理するため ポーズ中に背景をぼかすため (ブラー効果) 子Widgetにアンカーを適用するため 子Widgetで埋めるため #UE4 | #gcconf2020

17.

Widgetの配置例 範囲を必ず指定の大きさにするため ボタンで横幅を埋めるため ポーズメニュー上にオプション画面を被せるため #UE4 | #gcconf2020

18.

Main Widgetの配置例 Switcher Named Slot Safe Zone (表示物を切り替えて表示) (上位レイヤーに被せて表示) (可変レイアウト表示) #UE4 | #gcconf2020

19.

Sub Widgetの配置例 #UE4 | #gcconf2020

20.

Sub Widgetの配置例 全体をスケールするため 複数の子Widgetを管理するため #UE4 | #gcconf2020

21.

Sub Widgetの配置例 コンテンツを縦に敷き詰めて配置するため ポップアップの説明欄は固定サイズで表示するため #UE4 | #gcconf2020

22.

課題2: ウィジェットの使い分け方は? ● 機能を実現できるもの やりたいことを実現できるものを選択する ● 拡張性が良いもの コンテンツの追加や削除など変更に強いものを選択する ● コストが低いもの 同じ機能でもWidget別でコストの違いがある #UE4 | #gcconf2020

23.

Widgetの使い分け 例:複数の子Widgetをレイヤ管理 Canvas Panel vs Overlay 例:スクロール表示と操作 Scroll Box vs List View #UE4 | #gcconf2020

24.

課題3: ウィジェットを再利用するには? ● Widgetを拡張する コンテンツに併せてWidgetを使いやすくする ● Widgetを組み合わせる コンテンツに合った新しいWidgetを作成する #UE4 | #gcconf2020

25.

Widget (Text Block) [問題点] テキストの設定を毎回調整する必要がある #UE4 | #gcconf2020

26.

Textのフォントやサイズを簡単に設定できるようにした例 #UE4 | #gcconf2020

27.

テキストスタイルを指定して適用する例 #UE4 | #gcconf2020

28.

カスタムテキストスタイルの例 #UE4 | #gcconf2020

29.

Widget (Button) [問題点] 似たような機能やデザインのボタンが増える #UE4 | #gcconf2020

30.

例えばこのようなOK/Cancelの選択肢で同じボタンを使い回したい... #UE4 | #gcconf2020

31.

サブウィジェット上に配置した共有Widgetを選択して書き換え #UE4 | #gcconf2020

32.

課題4: アニメーションを再利用するには? ● 共通のWidgetを利用してリソースのみ差し替え 共通Widgetのアニメーションを常に利用する ● 親子関係を利用してアニメーションを適用 スケールやカラーなど親Widgetの変更に追従させる #UE4 | #gcconf2020

33.

アニメーションの再利用 ● 共通のWidgetを利用してリソースのみ差し替え Texture A Image Basic Button Animation Common Widget #UE4 | #gcconf2020 リソース 差し替え Basic Button Animation

34.

共有するWidgetにアニメーションを仕込んでおく #UE4 | #gcconf2020

35.

例えば、ボタンの場合はプレス時のアニメーション #UE4 | #gcconf2020

36.

配置先でリソースを差し替えておくことで、 #UE4 | #gcconf2020

37.

同じアニメーションを再生することが可能になる #UE4 | #gcconf2020

38.

ボタンイメージの更新 ボタンテキストの更新 共有Widgetは上書きするプロパティをDesignerに反映させるためにPreConstructでセット #UE4 | #gcconf2020

39.

アニメーションの再利用 ● 親子関係を利用してアニメーションを適用 Content Root 対象を 子に追加 Popup Content Root Animation #UE4 | #gcconf2020 Animation

40.

ポップアップを管理するためのマネージャクラス (親Widget)を準備 #UE4 | #gcconf2020

41.

ポップアップ共通のアニメーションを親のWidgetに仕込んでおく #UE4 | #gcconf2020

42.

アニメーションを適用するWidgetの子に対象を追加 #UE4 | #gcconf2020

43.

子Widgetに対してScale変更やOpacity変更が伝搬 #UE4 | #gcconf2020

44.

その他考察事項 ● キャンバスパネルの多用を避ける ● ネガティブパディングの設定を避ける ● 複製するならサブウィジェット化する、など #UE4 | #gcconf2020

45.

レイアウト設計のまとめ ● わかりやすさ、再利用、コストを意識する ● デザインするUIとの折り合いをつける #UE4 | #gcconf2020

46.

クラス設計 #UE4 | #gcconf2020

47.

クラス設計も迷う 再利用 複雑さ 分担 #UE4 | #gcconf2020

48.

Widgetのクラス設計についての例 UMGのベストプラクティス 公式ブログで紹介しているので参考になります #UE4 | #gcconf2020

49.

おさらい ウィジェットブループリントを新規作成する時にデフォルト のParent classはUser Widgetである #UE4 | #gcconf2020

50.

おさらい User Widgetクラスはレイアウトに配置したり追加したり 削除することができる #UE4 | #gcconf2020

51.

おさらい [!] Widget Blueprintの制約 ● Widget Blueprintは Designer上の配置情報を継承しない ● Parent #UE4 | #gcconf2020 配置情報が継承されないことを前提に設計する必要がある Child

52.

クラス設計での課題 ● Widgetの構造をどうするか? ● Widgetの実装をどうするか? ● Widgetの接続をどうするか? #UE4 | #gcconf2020

53.

課題1: Widgetの構造をどうするか? ● Widgetの役割に応じて適切に配置する Engineの機能とクラスを理解しておく ● ネイティブクラスを作成する プロジェクト独自の機能を追加して使いやすくする #UE4 | #gcconf2020

54.

Widget/UMG関連のEngineクラスの一部 UObject UVisual UWidget UPanelSlot UUserWidget UPanelWidget UImage Widget Blueprint UCanvasPanel UHorizontalBox ここだけは最低限覚えておく (それ以外はイメージだけでOK) #UE4 | #gcconf2020 UContentWidget UButton

55.

Widget/UMG関連のEngineクラスの一部 UObject UVisual UWidget UPanelSlot UUserWidget UPanelWidget UImage UCanvasPanel UHorizontalBox ユーザー定義のWidget #UE4 | #gcconf2020 UContentWidget UButton

56.

Widget/UMG関連のEngineクラスの一部 UObject UVisual 子を格納可能なWidget UWidget UPanelSlot UUserWidget UPanelWidget UImage UCanvasPanel UHorizontalBox UContentWidget UButton #UE4 | #gcconf2020

57.

Widget/UMG関連のEngineクラスの一部 UObject UVisual 水平方向に格納可能なWidget UWidget UPanelSlot UUserWidget UPanelWidget UImage UCanvasPanel UHorizontalBox レイヤー管理可能なWidget #UE4 | #gcconf2020 UContentWidget UButton

58.

Widget/UMG関連のEngineクラスの一部 UObject UVisual 1つの子を格納可能なWidget UWidget UPanelSlot UUserWidget UPanelWidget UImage UCanvasPanel UHorizontalBox UContentWidget UButton #UE4 | #gcconf2020

59.

Widget/UMG関連のEngineクラスの一部 UObject UVisual UWidget UPanelSlot UUserWidget UPanelWidget UImage UCanvasPanel UHorizontalBox UContentWidget UButton 独自の機能を持つWidget #UE4 | #gcconf2020

60.

Widget/UMG関連のEngineクラスの一部 Engine Native Blueprint UObject プロジェクトで作成するWidgetの クラス構成はどうする? UVisual UWidget UPanelSlot UUserWidget UPanelWidget UImage Widget Blueprint UCanvasPanel UHorizontalBox UContentWidget UButton #UE4 | #gcconf2020

61.

ActionRPG サンプルの場合 入力ボタン 入力ラベル #UE4 | #gcconf2020

62.

ActionRPG のクラス Engine Native UWidget UUserWidget シンプルな構成なので Parent Classは全てUserWidget WB_InputLabel #UE4 | #gcconf2020 WB_InputButton Blueprint

63.

ActionRPG のクラスを拡張 Engine Native UWidget UUserWidget プロジェクト独自の ネイティブクラスを追加 UCustomWidget UCustomButton WB_InputLabel #UE4 | #gcconf2020 WB_InputButton Blueprint

64.

ActionRPG のクラスを拡張 Engine UWidget UUserWidget プロジェクト独自の 共通Widget UCustomWidget UCustomButton WB_InputLabel #UE4 | #gcconf2020 WB_InputButton Native Blueprint

65.

ActionRPG のクラスを拡張 Engine UWidget 基本的にWidgetは 共通Widgetから作成 UUserWidget UCustomWidget UCustomButton WB_InputLabel #UE4 | #gcconf2020 WB_InputButton Native Blueprint

66.

ActionRPG のクラスを拡張 Engine UWidget ボタンWidget 共通の処理 UUserWidget UCustomWidget UCustomButton WB_InputLabel #UE4 | #gcconf2020 WB_InputButton Native Blueprint

67.

ActionRPG のクラスを拡張 Engine Native Blueprint UWidget UUserWidget 追加になっても 変更点のみの追加でOK UCustomWidget UCustomButton WB_InputLabel #UE4 | #gcconf2020 WB_InputButton WB_ButtonText

68.

プロジェクトで拡張するカスタムテキスト例 UWidget UTextLayoutWidget UTextBlock #UE4 | #gcconf2020 エンジンのデフォルトテキスト Engine Native Blueprint

69.

プロジェクトで拡張するカスタムテキスト例 UWidget UTextLayoutWidget UTextBlock UCustomText #UE4 | #gcconf2020 Engine プロジェクトのカスタムテキスト Native Blueprint

70.

課題2: Widgetの実装をどうするか? ● BlueprintとC++の線引きをしておく 責任の範囲を決めて実装する ● 可能な限り小さなWidgetに分割する 作業の競合、ロードなどに影響 #UE4 | #gcconf2020

71.

Widget実装の分担 Blueprint Class ● ● ● デザイナに配置したWidgetの制御 アニメーションの制御 C++から提供されたAPI アート Native Class (C++) ● ● ● #UE4 | #gcconf2020 データの受け渡し 複雑でコストが高い計算や処理 他クラスとのやりとり、UI更新の通知 エンジニア

72.

Widgetの実装分担 (Blueprint) 作業者A ● Designerの内容 ● Widget表示切替 ● アニメーション再生 #UE4 | #gcconf2020

73.

Widgetの実装分担 (C++) 作業者B ● トリガーイベント ● コンテンツ情報 ● BPで使用するAPI #UE4 | #gcconf2020

74.

Widgetの実装分担 (C++の実装ルール) ● Abstract Native Classは常に抽象化する ● NotBlueprintable 他のNative Classの基底クラスになるもの ● Blueprintable 派生してBlueprintで継承可能なもの #UE4 | #gcconf2020

75.

課題3: Widgetの接続をどうするか? ● Native ClassとSubsystemを活用する Widget Blueprint から直接別のクラスに参照するすることもできるが、 サブウィジェットはできる限り他のクラスと参照を持たない方が望ましい #UE4 | #gcconf2020

76.

https://www.slideshare.net/EpicGamesJapan/ue4-subsystem SubSystemを基礎から学びたい方はコチラがおすすめ #UE4 | #gcconf2020

77.

ネイティブクラス経由でWidgetの内容を更新する Engine Native Blueprint ● Initialize Health Bar Bar Widget Custom Player OnChangeValue() ● Update Apply Damage Health Bar Update Bar Widget Custom Player OnChangeValue() #UE4 | #gcconf2020 Action Apply Heal Item

78.

サブシステム経由でWidgetの内容を更新する Engine Native Blueprint ● Initialize Weather Icon Custom Widget Weather SubSystem OnChangeStatus() ● Update Change Weather Weather Icon Custom Widget Weather SubSystem OnChangeStatus() #UE4 | #gcconf2020 Action Time

79.

クラス設計のまとめ ● クラスの役割を明確にして分離する ● ネイティブクラスを効果的に利用する #UE4 | #gcconf2020

80.

目次 ● 設計 ● 仕組み ライフサイクル ● 最適化 #UE4 | #gcconf2020

81.

仕組みを理解するのは色々と役に立つ ● Widgetへの機能追加が容易になる ● ボトルネックの勘所が分かるようになる ● 最適化のオプションを理解して適用できる 効率化! #UE4 | #gcconf2020

82.

例:UIの処理が重いらしい とりあえずUnreal Insightsのグラフをみても 何が原因なのか分からない #UE4 | #gcconf2020

83.

UIの処理の仕組みが分かっていれば Tick SlatePrepass Paint AddElement たしかこう動いていたので #UE4 | #gcconf2020

84.

なんかUIの処理が重いらしい Misc SlatePrepass Paint Slateはこんなに処理負荷があった ⇒ 〇〇の最適化を入れよう #UE4 | #gcconf2020 Add Element

85.

おさらい Widgetは内部的に2つのパーツで構成される ● ● UWidget SWidget Engine :Slateに対する制御など他のObjectと対話 :レイアウトやインタラクションなどユーザーと対話 UWidget SWidget (制御部) (表示部) Widget #UE4 | #gcconf2020 User

86.

シンプルなWidgetの開始と終了 #UE4 | #gcconf2020

87.

シンプルなWidgetの開始と終了 Create OnScreen Remove #UE4 | #gcconf2020

88.

Widget Lifecycle Create OnScreen Tick Remove Destroy 生成 追加 更新 除去 破棄 5つのステップ #UE4 | #gcconf2020

89.

フローとオブジェクトの変化 フロー Create OnScreen Tick Remove Destroy オブジェクト UWidget #UE4 | #gcconf2020 UWidget UWidget SWidget SWidget UWidget

90.

Widget Lifecycle 生成 Create #UE4 | #gcconf2020 OnScreen Tick Remove Destroy

91.

Create Widget Create CreateWidget NewObject Initialize 生成処理開始 UWidgetと 関連するUObjectの生成 1度だけ呼ばれる #UE4 | #gcconf2020

92.

Create Widget (負荷ポイント) Create 参照オブジェクトの過多で ロード時のヒッチ等に注意 CreateWidget NewObject Widgetと関連 オブジェクトのロード Widgetと関連 オブジェクトの生成 #UE4 | #gcconf2020 Initialize

93.

Widget Lifecycle 追加 Create #UE4 | #gcconf2020 OnScreen Tick Remove Destroy

94.

OnScreen Widget OnScreen AddToViewport TakeWidget RebuildWidget Viewportに登録 SWidgetの生成開始 SWidgetの生成 Construct PreConstruct Synchronize Properties 構築完了 構築完了 (Begin Play) (Construction Script) #UE4 | #gcconf2020 UWidgetとSWidget の同期

95.

OnScreen Widget (負荷ポイント) 対象が多いとヒッチ発生 初期化の負荷分散も検討 OnScreen AddToViewport TakeWidget RebuildWidget スレート インスタンス生成 Construct PreConstruct Widget Blueprintの 初期化処理が集中 #UE4 | #gcconf2020 Synchronize Properties

96.

Widget Lifecycle 更新 Create #UE4 | #gcconf2020 OnScreen Tick Remove Destroy

97.

Tick Widget Tick SlatePrepass 子Widgetを含む スケールの適用 #UE4 | #gcconf2020 Paint AddElement 子Widgetを含む Render Batchの作成

98.

Tick Widget (負荷ポイント) Tick SlatePrepass 全てのWidgetを 走査してスケール適用 #UE4 | #gcconf2020 Widgetが多いと負荷になりがち キャッシュを使って負荷制御を Paint AddElement 全てのWidgetを 走査して描画情報作成

99.

Tick Widget …… …… …… …… …… x2.0 x1.0 x2.0 x1.0 x1.2 Id:1 Id:2 Id:3 Id:4 SlatePrepass Paint AddElement レイアウト決め 下書き作成 設計書作成 #UE4 | #gcconf2020

100.

スレッドを跨いで描画情報を通知 Game Threadは描画に必要な情報を作成するだけ ⇒ Render ThreadがRHIコマンドを作成してGPUに転送 Game Thread Render Thread #UE4 | #gcconf2020 レイアウト 決め 下書き 作成 設計書 作成 RHI Cmd 作成

101.

Widget Lifecycle 除去 Create #UE4 | #gcconf2020 OnScreen Tick Remove Destroy

102.

Remove Widget Remove RemoveFrom Parent Destruct ReleaseSlate Resources Viewportから削除 除去開始 (End Play) SWidgetの削除 #UE4 | #gcconf2020

103.

Remove Widget (負荷ポイント) Remove RemoveFrom Viewport Destruct ReleaseSlate Resources SWidgetの削除 #UE4 | #gcconf2020

104.

Widget Lifecycle 破棄 Create #UE4 | #gcconf2020 OnScreen Tick Remove Destroy

105.

Destroy Widget マップ遷移等によるGC Destroy BeginDestroy Destructor Widgetの破棄開始 UWidgetの削除 #UE4 | #gcconf2020

106.

Destroy Widget (負荷ポイント) マップ遷移等によるGC Destroy BeginDestroy GC対象のObject過多による ヒッチに注意 Destructor UWidgetと関連する オブジェクトの破棄 #UE4 | #gcconf2020

107.

ライフサイクルのまとめ ● フロー毎の負荷ポイントに注意する ● 動作を理解した上で次章の最適化を適用する #UE4 | #gcconf2020

108.

目次 ● 設計 ● 仕組み ● 最適化 #UE4 | #gcconf2020

109.

目次 ● デザイン ● メカニズム ● 最適化 ● オプション ● ツール #UE4 | #gcconf2020

110.

最適化オプション ● ● ● ● ● ● ● バインディング Tick Visibility Widget Blueprint Option Text Option Invalidation Box Global Invalidation #UE4 | #gcconf2020 ● ● ● ● Retainer Box リソース ネイティブ化 ウィジェットアニメーション

111.

バインディング Widgetへの値の反映はイベント駆動の実質一択 プロパティバインド、関数バインドは毎フレーム値の更新をチェックする ので高コスト故、殆ど使わない ● プロパティバインド #UE4 | #gcconf2020 イベント駆動

112.

Tick ● Tickでの実装 ● BlueprintのTickはコストが高いので極力避ける ● 必要な場合はNativeコードのTickを使う #UE4 | #gcconf2020

113.

Tick ● Tickの設定 ● デフォルトはAutoで自動的にON/OFFを切り替え ● NeverにするとTickを停止できるが以下の機能が制限される ● ● ● ● #UE4 | #gcconf2020 Widget Animation Latent Action Native Tick Blueprint Tick

114.

Tick ● 補足 Autoに設定されたNative TickはいつONとなるか? ● ● ● ● Latent Action (Delayなど)がトリガーされる アニメーションがトリガーされる BlueprintのTickイベントが実装されている ネイティブクラスで指定されていない UCLASS(meta = (DisableNativeTick)) Tickを利用しない場合は、meta指定がおススメ #UE4 | #gcconf2020

115.

Visibility Widgetの可視性やヒットテスト可否の設定 ● インタラクションだけでなくパフォーマンスにも影響 ● その時の状況に応じて適切にコントロールする必要がある #UE4 | #gcconf2020

116.

Visibility ● ● ● デフォルトは Visbility (最もコストが高い) 設定になっている Widgetを表示する場合は判定が不要ならNot Hit-Testableを利用 Widgetを表示しない場合はCollapsedがコスト的に望ましい プリセット 表示 ヒット判定 レイアウト更新 Visible あり あり あり Not Hit-Testable (Self Only) あり 自身はなし あり Not Hit-Testable (Self&All childeren) あり なし あり Hidden なし なし あり Collapsed なし なし なし #UE4 | #gcconf2020 高 コ ス ト 低

117.

Widget Blueprint Option ● Force Slow Construction Path ● ● 無効にすると、Widget Templateを利用して高速にTreeを構築 有効にすると、構築コストがかかるがアセットサイズを抑制 ● Support Dynamic Creation ● ● #UE4 | #gcconf2020 無効にすると、動的な生成を許可しない代わりにアセットサイズを抑制 有効にすると、CreateWidget()による動的生成を許可する

118.

Text Option ● Wrap with Invalidation Panel ● ● Invalidation Panelを生成してText Blockを自動でラップする機能 Text BlockとInvalidation Panelの更新のトレードオフ ● Simple Text Mode ● ● #UE4 | #gcconf2020 テキスト整形, 折り返し, 位置補正処理を無効化して高速化する テキスト機能とパフォーマンスのトレードオフ

119.

Invalidation Box ● 機能 子Widgetをキャッシュすることで更新処理をスキップして高速化 フレーム1 Invalidation Box 未適用 フレーム2 フレーム3 フレーム4 処理 Invalidation Box 適用 IBを適用することで更新処理による負荷を軽減 #UE4 | #gcconf2020 フレーム5

120.

Invalidation Box ● 使い方 Invalidation Boxで対象のWidget をラップ、効果はラップした対象 全てに影響 ● 設定 CanCacheを有効にする (デフォルト有効) #UE4 | #gcconf2020

121.

Invalidation Box 適用することで定常的なwidgetの更新コストを抑制する 適用前 #UE4 | #gcconf2020 適用後

122.

適用前 Tick SlatePrepass Paint AddElement 適用後 Tick SlatePrepass #UE4 | #gcconf2020 キャッシュを利用して処理スキップ Paint AddElement

123.

Global Invalidation ● 機能 (早期公開版) ● Invalidation Panelのキャッシュ効果をSlate全体に適用する機能 ● Invalidation BoxとGlobal Invalidationの併用は不可 ● レイアウト変更が生じた際にも自動的にキャッシュを無効化 ● 使い方 ● ”Slate.EnableGlobalInvalidation 1”を入力 ● #UE4 | #gcconf2020 PIE時は ”New Editor Window (PIE)”のみ有効

124.

Global Invalidation ● 効果検証 単にImageを2000枚並べただけのケース #UE4 | #gcconf2020

125.

Global Invalidation Disable Enable Invalidation Panelを配置せずとも Slate全体にキャッシュ適用されてコストダウン #UE4 | #gcconf2020

126.

Global Invalidation Disable Enable 全てのBatch Elementはキャッシュされる 毎フレームのPaint処理もキャッシュによってコスト削減 #UE4 | #gcconf2020

127.

Retainer Box ● 機能 Render Targetに描画して更新処理を任意にスキップする フレーム1 Retainer Box 未適用 フレーム2 フレーム3 フレーム4 処理 Retainer Box 適用 RBを適用することで更新処理による負荷を軽減 #UE4 | #gcconf2020 フレーム5

128.

Retainer Box ● 使い方 Retainer Boxで対象のWidgetを ラップ、効果はラップした対象全 てに影響 ● 設定 5フレームの周期で、フェーズ0 (1フレーム目)で更新処理を行う場 合は右図のように設定する #UE4 | #gcconf2020

129.

Retainer Box 結果として下記のように, 1フレーム, 6フレーム, ...と、5フレーム毎 に更新が継続して実行されるように #UE4 | #gcconf2020

130.

リソース (Texture) Export形式 .png/.tgaでエクスポート、圧縮の観点から2のべき乗サイズを利用 ● 圧縮形式 [UserInterface2D]は非圧縮 通常は[DXT]が使用されるが用途次第で変える Texture Groupは[UI]を利用 ● ● ● アルファ ● ● #UE4 | #gcconf2020 リソースサイズが大きくなるため必要なものに限定して利用 単なるフェードで半透明を適用するならWidgetの機能で可能

131.

リソース (Texture) Texture Size ● ● テクスチャでメモリを占有しすぎないようにテクスチャサイズを調整 小さい表示物、重要でない表示物に巨大なサイズを割り当てない ● ● テクスチャ解像度がターゲットと一致しない場合は[No Mip Maps] テクスチャを縮小して使用する場合などは[From Texture Group] Mips #UE4 | #gcconf2020

132.

ネイティブ化 Widget Blueprintをネイティブ化は効果がある...? メリット ● ● UObjectが減ることでロードやGC時間が改善できるが効果は実装次第 CPU処理はBlueprintアクセスのコストが削減されて恩恵を受ける デメリット ネイティブ化されたコードを含むサイズの増加 ● Widgetで発生した問題の切り分けの複雑化 ● #UE4 | #gcconf2020

133.

ネイティブ化 変数などのUObjectは変わらず、マクロなどBPに影響 ネイティブ化前 #UE4 | #gcconf2020 ネイティブ化後

134.

ウィジェットアニメーション ● 今までの課題 ● ● 複雑なアニメーションの高い評価コスト インスタンス化されたアニメーションによる長いロード ● 改善された点 ● ● #UE4 | #gcconf2020 UE4.22 : Widget Animationを共通化 UE4.25:UProperty → FProperty に置き換え

135.

● 4.22以前 (オブジェクト数が多かった) Button Blueprint Open Anim ボタンを2つ 追加 Press Anim Hover Anim ● Button Button Blueprint Button Blueprint Blueprint Open Anim Open Anim PressOpen AnimAnim Press Anim Hover AnimAnim Press Hover Anim Hover Anim 4.22以降 (オブジェクト数が削減された) Button Blueprint Open Anim Press Anim Hover Anim #UE4 | #gcconf2020 ボタンを2つ 追加 Button Button Blueprint Button Blueprint Blueprint Open Anim Press Anim Hover Anim

136.

Widget AnimationとUObject数の推移 Case1 :アニメーションなしの状態 アニメーション なし Class Total #UE4 | #gcconf2020 Count 39 NumKB 11.89

137.

Widget AnimationとUObject数の推移 Case2 :アニメーション1つ追加 1アニメーション Class Total #UE4 | #gcconf2020 Count 42 NumKB 13.42

138.

Widget AnimationとUObject数の推移 Case3 :アニメーション1つとTransformトラック1つを追加 1アニメーション+1トラック Class Total #UE4 | #gcconf2020 Count 46 NumKB 16.17

139.

Widget AnimationとUObject数の推移 アニメーションやトラックを追加するとコストが増えます #UE4 | #gcconf2020

140.

Widget AnimationとUObject数の推移 アニメーションやトラック追加時のObject数の変化 (UE4.24) #UE4 | #gcconf2020

141.

Engine VersionとUObject推移 バージョンによる推移は? 1アニメーション+1トラック (UE4.24) Class Total Count NumKB 46 16.17 1アニメーション+1トラック (UE4.25) Class Total #UE4 | #gcconf2020 Count ??? NumKB ???

142.

Engine VersionとUObject推移 Object数は以前の40%削減、サイズは50%超の削減 #UE4 | #gcconf2020

143.

Engine VersionとUObject推移 Widget数による傾向は? 1アニメーション+1トラック × 1 Class Total Count 46 NumKB 16.17 1アニメーション+1トラック × 10 Class Total #UE4 | #gcconf2020 Count ??? NumKB ???

144.

Engine VersionとUObject推移 以前に比べてWidget数が増えても Object数は54%削減、サイズは71%縮小 #UE4 | #gcconf2020

145.

Engine VersionとUObject推移 Engine Versionの更新に伴うAnimation付きWidgetのObject数の変化 #UE4 | #gcconf2020

146.

デバッグ ● パフォーマンス計測 ● ● Stats Unreal Insights ● 設定の確認 ● ● #UE4 | #gcconf2020 Widget Reflector Asset Audit ● 動作の追跡 ● ● Slate Debugger Debug Tools

147.

デバッグ コンソールコマンド:Stat Slate ● スレートに関するパフォーマンスを計測するコマンド ● Statsを描画するコストが追加されるので目安程度に ● ただしボトルネックのポイントを特定するのに有用 #UE4 | #gcconf2020

148.

Stat Slate レイアウト更新処理 ⇒ 表示物(ジオメトリ)が多い エレメント追加処理 ⇒ バッチ処理が多い #UE4 | #gcconf2020

149.

デバッグ Unreal Insights ● アプリケーションのパフォーマンスをプロファイルする ● Slate専用イベント (“Stat Slate”の対象)もキャプチャ可能 #UE4 | #gcconf2020

150.

Unreal Insights レイアウト更新処理 ⇒ 表示物(ジオメトリ)が多い Tick処理 ⇒ Tickが動いているSlateが多い #UE4 | #gcconf2020

151.

デバッグ Widget Reflector ● 利用中のリソースや設定をキャプチャして解析できるツール [UE4] Widget Reflectorを使ってリソースや設定を調べよう #UE4 | #gcconf2020

152.

デバッグ Asset Audit ● アセットの情報をリスト化して確認できるツール #UE4 | #gcconf2020

153.

Asset Audit Tick駆動予測 ⇒ 適切な稼働か? Property Bind数 ⇒ イベント駆動の方法に変更? #UE4 | #gcconf2020

154.

デバッグ コンソールコマンド:SlateDebugger.Start ● フォーカスの移行、キャプチャ、入力系イベントなどの Slateイベントをログに出力 #UE4 | #gcconf2020

155.

デバッグ Debug Tools ● Slateに関連する様々なデバッグ機能を提供するツール #UE4 | #gcconf2020

156.

Test Suite #UE4 | #gcconf2020

157.

関連リンク ● 公式ドキュメント UMG (Unreal Motion Graphics) のベスト プラクティス ● 公式ブログ UMG のベスト プラクティス ● 公式スライド 猫でも分かるUMG ● UE4 ANSWERHUB 情報共有:UMGミーティングの資料 #UE4 | #gcconf2020

158.

#UE4 | #gcconf2020