Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

UE4で作成するUIと最適化手法

1.557 visualizaciones

Publicado el

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

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

Publicado en: Ingeniería
  • Sé el primero en comentar

UE4で作成するUIと最適化手法

  1. 1. #UE4 | #gcconf2020 UE4で作成するUIと最適化手法 Epic Games Japan Software Engineer, Developer Relations 鍬農 健二郎
  2. 2. #UE4 | #gcconf2020 何故UIをやるのか?
  3. 3. #UE4 | #gcconf2020 概要 ● 目的 ● UMGを使って効率的にUIを構築できる ● UIの最適化方法を適用できる ● 対象 ● UMGを利用するアーティスト ● 実装や最適化をするエンジニア、TA ● 適用範囲 UE 4.25
  4. 4. #UE4 | #gcconf2020 本日のお題 設計 仕組み 最適化
  5. 5. #UE4 | #gcconf2020 本日のお題 ● 設計 ● レイアウト設計 … アート ● クラス設計 … エンジニア ● 仕組み ● ライフサイクル … エンジニア ● 最適化 ● オプション … アート、エンジニア ● デバッグ … アート、エンジニア
  6. 6. #UE4 | #gcconf2020 UMGを基礎から学びたい方はコチラがおすすめ https://www.slideshare.net/EpicGamesJapan/umg-80334310
  7. 7. #UE4 | #gcconf2020 目次 ● 設計 ● レイアウト設計 ● クラス設計 ● 仕組み ● 最適化
  8. 8. #UE4 | #gcconf2020 レイアウト設計
  9. 9. #UE4 | #gcconf2020 レイアウト設計は悩む 再利用 見栄え 無駄なく
  10. 10. #UE4 | #gcconf2020 おさらい ● Widget 小さな機能単位の表示要素 ● User Widget Widgetを組み合わせて作成する表示要素 ⇒ Main Widget, Sub Widget
  11. 11. #UE4 | #gcconf2020 Widget Sub Widget Widget
  12. 12. #UE4 | #gcconf2020 User Widget レイアウト Sub WidgetMain Widget ボタンセット アタックボタン
  13. 13. #UE4 | #gcconf2020 レイアウト設計での課題 ● ウィジェットを配置する基準は? ● ウィジェットの使い分け方は? ● ウィジェットを再利用する方法は? ● アニメーションを再利用する方法は?
  14. 14. #UE4 | #gcconf2020 課題1:ウィジェットを配置する基準は? ● ウィジェットを配置する理由を意識する 何故それを使ったか説明できるように配置する ● レイアウトが常に変わることを意識する レイアウト変更、マルチプラットフォームに対応
  15. 15. #UE4 | #gcconf2020 Widgetの配置例
  16. 16. #UE4 | #gcconf2020 Widgetの配置例 複数の子Widgetをレイヤー管理するため ポーズ中に背景をぼかすため (ブラー効果) 子Widgetにアンカーを適用するため 子Widgetで埋めるため
  17. 17. #UE4 | #gcconf2020 Widgetの配置例 ポーズメニュー上にオプション画面を被せるため ボタンで横幅を埋めるため 範囲を必ず指定の大きさにするため
  18. 18. #UE4 | #gcconf2020 Main Widgetの配置例 Named Slot (上位レイヤーに被せて表示) Safe Zone (可変レイアウト表示) Switcher (表示物を切り替えて表示)
  19. 19. #UE4 | #gcconf2020 Sub Widgetの配置例
  20. 20. #UE4 | #gcconf2020 Sub Widgetの配置例 全体をスケールするため 複数の子Widgetを管理するため
  21. 21. #UE4 | #gcconf2020 Sub Widgetの配置例 コンテンツを縦に敷き詰めて配置するため ポップアップの説明欄は固定サイズで表示するため
  22. 22. #UE4 | #gcconf2020 課題2: ウィジェットの使い分け方は? ● 機能を実現できるもの やりたいことを実現できるものを選択する ● 拡張性が良いもの コンテンツの追加や削除など変更に強いものを選択する ● コストが低いもの 同じ機能でもWidget別でコストの違いがある
  23. 23. #UE4 | #gcconf2020 Widgetの使い分け 例:複数の子Widgetをレイヤ管理 Canvas Panel vs Overlay 例:スクロール表示と操作 Scroll Box vs List View
  24. 24. #UE4 | #gcconf2020 課題3: ウィジェットを再利用するには? ● Widgetを拡張する コンテンツに併せてWidgetを使いやすくする ● Widgetを組み合わせる コンテンツに合った新しいWidgetを作成する
  25. 25. #UE4 | #gcconf2020 Widget (Text Block) [問題点] テキストの設定を毎回調整する必要がある
  26. 26. #UE4 | #gcconf2020 Textのフォントやサイズを簡単に設定できるようにした例
  27. 27. #UE4 | #gcconf2020 テキストスタイルを指定して適用する例
  28. 28. #UE4 | #gcconf2020 カスタムテキストスタイルの例
  29. 29. #UE4 | #gcconf2020 Widget (Button) [問題点] 似たような機能やデザインのボタンが増える
  30. 30. #UE4 | #gcconf2020 例えばこのようなOK/Cancelの選択肢で同じボタンを使い回したい...
  31. 31. #UE4 | #gcconf2020 サブウィジェット上に配置した共有Widgetを選択して書き換え
  32. 32. #UE4 | #gcconf2020 課題4: アニメーションを再利用するには? ● 共通のWidgetを利用してリソースのみ差し替え 共通Widgetのアニメーションを常に利用する ● 親子関係を利用してアニメーションを適用 スケールやカラーなど親Widgetの変更に追従させる
  33. 33. #UE4 | #gcconf2020 アニメーションの再利用 ● 共通のWidgetを利用してリソースのみ差し替え Basic Button Animation Image リソース 差し替え Basic Button Animation Texture A Common Widget
  34. 34. #UE4 | #gcconf2020 共有するWidgetにアニメーションを仕込んでおく
  35. 35. #UE4 | #gcconf2020 例えば、ボタンの場合はプレス時のアニメーション
  36. 36. #UE4 | #gcconf2020 配置先でリソースを差し替えておくことで、
  37. 37. #UE4 | #gcconf2020 同じアニメーションを再生することが可能になる
  38. 38. #UE4 | #gcconf2020 共有Widgetは上書きするプロパティをDesignerに反映させるためにPreConstructでセット ボタンテキストの更新 ボタンイメージの更新
  39. 39. #UE4 | #gcconf2020 アニメーションの再利用 ● 親子関係を利用してアニメーションを適用 Content Root Animation Content Root Animation Popup 対象を 子に追加
  40. 40. #UE4 | #gcconf2020 ポップアップを管理するためのマネージャクラス (親Widget)を準備
  41. 41. #UE4 | #gcconf2020 ポップアップ共通のアニメーションを親のWidgetに仕込んでおく
  42. 42. #UE4 | #gcconf2020 アニメーションを適用するWidgetの子に対象を追加
  43. 43. #UE4 | #gcconf2020 子Widgetに対してScale変更やOpacity変更が伝搬
  44. 44. #UE4 | #gcconf2020 その他考察事項 ● キャンバスパネルの多用を避ける ● ネガティブパディングの設定を避ける ● 複製するならサブウィジェット化する、など
  45. 45. #UE4 | #gcconf2020 レイアウト設計のまとめ ● わかりやすさ、再利用、コストを意識する ● デザインするUIとの折り合いをつける
  46. 46. #UE4 | #gcconf2020 クラス設計
  47. 47. #UE4 | #gcconf2020 クラス設計も迷う 再利用 複雑さ 分担
  48. 48. #UE4 | #gcconf2020 Widgetのクラス設計についての例 UMGのベストプラクティス 公式ブログで紹介しているので参考になります
  49. 49. #UE4 | #gcconf2020 おさらい ウィジェットブループリントを新規作成する時にデフォルト のParent classはUser Widgetである
  50. 50. #UE4 | #gcconf2020 おさらい User Widgetクラスはレイアウトに配置したり追加したり 削除することができる
  51. 51. #UE4 | #gcconf2020 おさらい [!] Widget Blueprintの制約 ● Widget Blueprintは Designer上の配置情報を継承しない ● 配置情報が継承されないことを前提に設計する必要がある Parent Child
  52. 52. #UE4 | #gcconf2020 クラス設計での課題 ● Widgetの構造をどうするか? ● Widgetの実装をどうするか? ● Widgetの接続をどうするか?
  53. 53. #UE4 | #gcconf2020 課題1: Widgetの構造をどうするか? ● Widgetの役割に応じて適切に配置する Engineの機能とクラスを理解しておく ● ネイティブクラスを作成する プロジェクト独自の機能を追加して使いやすくする
  54. 54. #UE4 | #gcconf2020 Widget/UMG関連のEngineクラスの一部 UCanvasPanel UButton UUserWidget UVisual UObject UWidget UPanelWidget UHorizontalBox UContentWidget UImage UPanelSlotUWidget Widget Blueprint ここだけは最低限覚えておく (それ以外はイメージだけでOK)
  55. 55. #UE4 | #gcconf2020 Widget/UMG関連のEngineクラスの一部 UCanvasPanel UButton UUserWidget UVisual UObject UWidget UPanelWidget UHorizontalBox UContentWidget UImage UPanelSlot ユーザー定義のWidget
  56. 56. #UE4 | #gcconf2020 Widget/UMG関連のEngineクラスの一部 UCanvasPanel UButton UUserWidget UVisual UObject UWidget UPanelWidget UHorizontalBox UContentWidget UImage UPanelSlot 子を格納可能なWidget
  57. 57. #UE4 | #gcconf2020 Widget/UMG関連のEngineクラスの一部 UCanvasPanel UButton UUserWidget UVisual UObject UWidget UPanelWidget UHorizontalBox UContentWidget UImage UPanelSlot レイヤー管理可能なWidget 水平方向に格納可能なWidget
  58. 58. #UE4 | #gcconf2020 Widget/UMG関連のEngineクラスの一部 UCanvasPanel UButton UUserWidget UVisual UObject UWidget UPanelWidget UHorizontalBox UContentWidget UImage UPanelSlot 1つの子を格納可能なWidget
  59. 59. #UE4 | #gcconf2020 Widget/UMG関連のEngineクラスの一部 UCanvasPanel UButton UUserWidget UVisual UObject UWidget UPanelWidget UHorizontalBox UContentWidget UImage UPanelSlot 独自の機能を持つWidget
  60. 60. #UE4 | #gcconf2020 Widget/UMG関連のEngineクラスの一部 UCanvasPanel UButton UUserWidget UVisual UObject UWidget UPanelWidget UHorizontalBox UContentWidget UImage UPanelSlotUWidget Widget Blueprint プロジェクトで作成するWidgetの クラス構成はどうする? Native BlueprintEngine
  61. 61. #UE4 | #gcconf2020 ActionRPG サンプルの場合 入力ラベル 入力ボタン
  62. 62. #UE4 | #gcconf2020 ActionRPG のクラス UUserWidget UWidgetUWidget WB_InputButton Native BlueprintEngine シンプルな構成なので Parent Classは全てUserWidget WB_InputLabel
  63. 63. #UE4 | #gcconf2020 ActionRPG のクラスを拡張 UWidgetUWidget Native BlueprintEngine プロジェクト独自の ネイティブクラスを追加 WB_InputLabel UCustomWidget UCustomButton UUserWidget WB_InputButton
  64. 64. #UE4 | #gcconf2020 ActionRPG のクラスを拡張 UWidgetUWidget Native BlueprintEngine WB_InputLabel UCustomWidget UCustomButton UUserWidget WB_InputButton プロジェクト独自の 共通Widget
  65. 65. #UE4 | #gcconf2020 ActionRPG のクラスを拡張 UWidgetUWidget Native BlueprintEngine WB_InputLabel UCustomWidget UCustomButton UUserWidget WB_InputButton 基本的にWidgetは 共通Widgetから作成
  66. 66. #UE4 | #gcconf2020 ActionRPG のクラスを拡張 UWidgetUWidget Native BlueprintEngine WB_InputLabel UCustomWidget UCustomButton UUserWidget WB_InputButton ボタンWidget 共通の処理
  67. 67. #UE4 | #gcconf2020 ActionRPG のクラスを拡張 UWidgetUWidget Native BlueprintEngine WB_InputLabel UCustomWidget UCustomButton UUserWidget WB_InputButton 追加になっても 変更点のみの追加でOK WB_ButtonText
  68. 68. #UE4 | #gcconf2020 UWidgetUWidget プロジェクトで拡張するカスタムテキスト例 UTextBlock UTextLayoutWidget エンジンのデフォルトテキスト Native BlueprintEngine
  69. 69. #UE4 | #gcconf2020 プロジェクトのカスタムテキスト プロジェクトで拡張するカスタムテキスト例 UWidgetUWidget UTextBlock UCustomText UTextLayoutWidget Native BlueprintEngine
  70. 70. #UE4 | #gcconf2020 課題2: Widgetの実装をどうするか? ● BlueprintとC++の線引きをしておく 責任の範囲を決めて実装する ● 可能な限り小さなWidgetに分割する 作業の競合、ロードなどに影響
  71. 71. #UE4 | #gcconf2020 Widget実装の分担 Blueprint Class ● デザイナに配置したWidgetの制御 ● アニメーションの制御 ● C++から提供されたAPI Native Class (C++) ● データの受け渡し ● 複雑でコストが高い計算や処理 ● 他クラスとのやりとり、UI更新の通知 エンジニア アート
  72. 72. #UE4 | #gcconf2020 Widgetの実装分担 (Blueprint) 作業者A ● Designerの内容 ● Widget表示切替 ● アニメーション再生
  73. 73. #UE4 | #gcconf2020 Widgetの実装分担 (C++) 作業者B ● トリガーイベント ● コンテンツ情報 ● BPで使用するAPI
  74. 74. #UE4 | #gcconf2020 Widgetの実装分担 (C++の実装ルール) ● Abstract Native Classは常に抽象化する ● NotBlueprintable 他のNative Classの基底クラスになるもの ● Blueprintable 派生してBlueprintで継承可能なもの
  75. 75. #UE4 | #gcconf2020 課題3: Widgetの接続をどうするか? ● Native ClassとSubsystemを活用する Widget Blueprint から直接別のクラスに参照するすることもできるが、 サブウィジェットはできる限り他のクラスと参照を持たない方が望ましい
  76. 76. #UE4 | #gcconf2020 SubSystemを基礎から学びたい方はコチラがおすすめ https://www.slideshare.net/EpicGamesJapan/ue4-subsystem
  77. 77. #UE4 | #gcconf2020 ネイティブクラス経由でWidgetの内容を更新する Health Bar Bar Widget Custom Player ● Initialize Health Bar Bar Widget Custom Player ● Update Action OnChangeValue() OnChangeValue() Apply Damage Update ItemApply Heal Native BlueprintEngine
  78. 78. #UE4 | #gcconf2020 サブシステム経由でWidgetの内容を更新する Weather Icon Custom Widget Weather SubSystem ● Initialize Weather Icon Custom Widget Weather SubSystem ● Update Action OnChangeStatus() OnChangeStatus() Change Weather Time Native BlueprintEngine
  79. 79. #UE4 | #gcconf2020 クラス設計のまとめ ● クラスの役割を明確にして分離する ● ネイティブクラスを効果的に利用する
  80. 80. #UE4 | #gcconf2020 目次 ● 設計 ● 仕組み ライフサイクル ● 最適化
  81. 81. #UE4 | #gcconf2020 仕組みを理解するのは色々と役に立つ ● Widgetへの機能追加が容易になる ● ボトルネックの勘所が分かるようになる ● 最適化のオプションを理解して適用できる 効率化!
  82. 82. #UE4 | #gcconf2020 例:UIの処理が重いらしい とりあえずUnreal Insightsのグラフをみても 何が原因なのか分からない
  83. 83. #UE4 | #gcconf2020 Tick UIの処理の仕組みが分かっていれば たしかこう動いていたので SlatePrepass Paint AddElement
  84. 84. #UE4 | #gcconf2020 なんかUIの処理が重いらしい Misc Slateはこんなに処理負荷があった ⇒ 〇〇の最適化を入れよう SlatePrepass Paint Add Element
  85. 85. #UE4 | #gcconf2020 Widget おさらい Widgetは内部的に2つのパーツで構成される ● UWidget :Slateに対する制御など他のObjectと対話 ● SWidget :レイアウトやインタラクションなどユーザーと対話 UWidget (制御部) Engine UserSWidget (表示部)
  86. 86. #UE4 | #gcconf2020 シンプルなWidgetの開始と終了
  87. 87. #UE4 | #gcconf2020 シンプルなWidgetの開始と終了 Create OnScreen Remove
  88. 88. #UE4 | #gcconf2020 Widget Lifecycle Create OnScreen Tick Remove 生成 追加 更新 除去 5つのステップ Destroy 破棄
  89. 89. #UE4 | #gcconf2020 フローとオブジェクトの変化 Create OnScreen Tick Remove Destroy UWidget フロー オブジェクト UWidget SWidget UWidget SWidget UWidget
  90. 90. #UE4 | #gcconf2020 Widget Lifecycle Create OnScreen Tick Remove Destroy 生成
  91. 91. #UE4 | #gcconf2020 Create Widget 1度だけ呼ばれる生成処理開始 UWidgetと 関連するUObjectの生成 Create CreateWidget NewObject Initialize
  92. 92. #UE4 | #gcconf2020 Create Widget (負荷ポイント) Widgetと関連 オブジェクトのロード Create CreateWidget NewObject Initialize Widgetと関連 オブジェクトの生成 参照オブジェクトの過多で ロード時のヒッチ等に注意
  93. 93. #UE4 | #gcconf2020 Widget Lifecycle Create OnScreen Tick Remove Destroy 追加
  94. 94. #UE4 | #gcconf2020 OnScreen Widget OnScreen AddToViewport TakeWidget RebuildWidget Synchronize Properties Construct Viewportに登録 SWidgetの生成開始 構築完了 (Begin Play) UWidgetとSWidget の同期 PreConstruct 構築完了 (Construction Script) SWidgetの生成
  95. 95. #UE4 | #gcconf2020 OnScreen Widget (負荷ポイント) OnScreen AddToViewport TakeWidget RebuildWidget Synchronize Properties Construct Widget Blueprintの 初期化処理が集中 PreConstruct スレート インスタンス生成 対象が多いとヒッチ発生 初期化の負荷分散も検討
  96. 96. #UE4 | #gcconf2020 Widget Lifecycle Create OnScreen Tick Remove Destroy 更新
  97. 97. #UE4 | #gcconf2020 Tick Widget Tick SlatePrepass Paint AddElement 子Widgetを含む スケールの適用 子Widgetを含む Render Batchの作成
  98. 98. #UE4 | #gcconf2020 Tick Widget (負荷ポイント) Tick SlatePrepass Paint AddElement 全てのWidgetを 走査してスケール適用 全てのWidgetを 走査して描画情報作成 Widgetが多いと負荷になりがち キャッシュを使って負荷制御を
  99. 99. #UE4 | #gcconf2020 Tick Widget レイアウト決め 下書き作成 設計書作成 SlatePrepass Paint AddElement …… x2.0 …… x1.0 …… x2.0 …… x1.0 …… x1.2 Id:1 Id:2 Id:3Id:4
  100. 100. #UE4 | #gcconf2020 スレッドを跨いで描画情報を通知 Game Threadは描画に必要な情報を作成するだけ  ⇒ Render ThreadがRHIコマンドを作成してGPUに転送 Game Thread Render Thread レイアウト 決め 下書き 作成 設計書 作成 RHI Cmd 作成
  101. 101. #UE4 | #gcconf2020 Widget Lifecycle Create OnScreen Tick Remove Destroy 除去
  102. 102. #UE4 | #gcconf2020 Remove Widget Remove RemoveFrom Parent Destruct ReleaseSlate Resources SWidgetの削除Viewportから削除 除去開始 (End Play)
  103. 103. #UE4 | #gcconf2020 Remove Widget (負荷ポイント) Remove RemoveFrom Viewport Destruct ReleaseSlate Resources SWidgetの削除
  104. 104. #UE4 | #gcconf2020 Widget Lifecycle Create OnScreen Tick Remove Destroy 破棄
  105. 105. #UE4 | #gcconf2020 Destroy Widget Destroy BeginDestroy Destructor マップ遷移等によるGC UWidgetの削除Widgetの破棄開始
  106. 106. #UE4 | #gcconf2020 Destroy Widget (負荷ポイント) Destroy BeginDestroy Destructor UWidgetと関連する オブジェクトの破棄 GC対象のObject過多による ヒッチに注意 マップ遷移等によるGC
  107. 107. #UE4 | #gcconf2020 ライフサイクルのまとめ ● フロー毎の負荷ポイントに注意する ● 動作を理解した上で次章の最適化を適用する
  108. 108. #UE4 | #gcconf2020 目次 ● 設計 ● 仕組み ● 最適化
  109. 109. #UE4 | #gcconf2020 目次 ● デザイン ● メカニズム ● 最適化 ● オプション ● ツール
  110. 110. #UE4 | #gcconf2020 最適化オプション ● バインディング ● Tick ● Visibility ● Widget Blueprint Option ● Text Option ● Invalidation Box ● Global Invalidation ● Retainer Box ● リソース ● ネイティブ化 ● ウィジェットアニメーション
  111. 111. #UE4 | #gcconf2020 バインディング Widgetへの値の反映はイベント駆動の実質一択 ● プロパティバインド、関数バインドは毎フレーム値の更新をチェックする ので高コスト故、殆ど使わない プロパティバインド イベント駆動
  112. 112. #UE4 | #gcconf2020 Tick ● Tickでの実装 ● BlueprintのTickはコストが高いので極力避ける ● 必要な場合はNativeコードのTickを使う
  113. 113. #UE4 | #gcconf2020 Tick ● Tickの設定 ● デフォルトはAutoで自動的にON/OFFを切り替え ● NeverにするとTickを停止できるが以下の機能が制限される ● Widget Animation ● Latent Action ● Native Tick ● Blueprint Tick
  114. 114. #UE4 | #gcconf2020 Tick ● 補足 Autoに設定されたNative TickはいつONとなるか? ● Latent Action (Delayなど)がトリガーされる ● アニメーションがトリガーされる ● BlueprintのTickイベントが実装されている ● ネイティブクラスで指定されていない UCLASS(meta = (DisableNativeTick)) Tickを利用しない場合は、meta指定がおススメ
  115. 115. #UE4 | #gcconf2020 Visibility Widgetの可視性やヒットテスト可否の設定 ● インタラクションだけでなくパフォーマンスにも影響 ● その時の状況に応じて適切にコントロールする必要がある
  116. 116. #UE4 | #gcconf2020 Visibility ● デフォルトは Visbility (最もコストが高い) 設定になっている ● Widgetを表示する場合は判定が不要ならNot Hit-Testableを利用 ● Widgetを表示しない場合はCollapsedがコスト的に望ましい プリセット 表示 ヒット判定 レイアウト更新 Visible あり あり あり Not Hit-Testable (Self Only) あり 自身はなし あり Not Hit-Testable (Self&All childeren) あり なし あり Hidden なし なし あり Collapsed なし なし なし コ ス ト 低 高
  117. 117. #UE4 | #gcconf2020 Widget Blueprint Option ● Force Slow Construction Path ● 無効にすると、Widget Templateを利用して高速にTreeを構築 ● 有効にすると、構築コストがかかるがアセットサイズを抑制 ● Support Dynamic Creation ● 無効にすると、動的な生成を許可しない代わりにアセットサイズを抑制 ● 有効にすると、CreateWidget()による動的生成を許可する
  118. 118. #UE4 | #gcconf2020 Text Option ● Wrap with Invalidation Panel ● Invalidation Panelを生成してText Blockを自動でラップする機能 ● Text BlockとInvalidation Panelの更新のトレードオフ ● Simple Text Mode ● テキスト整形, 折り返し, 位置補正処理を無効化して高速化する ● テキスト機能とパフォーマンスのトレードオフ
  119. 119. #UE4 | #gcconf2020 Invalidation Box ● 機能 子Widgetをキャッシュすることで更新処理をスキップして高速化 処理 フレーム1 フレーム2 フレーム3 フレーム4 フレーム5 Invalidation Box 未適用 Invalidation Box 適用 IBを適用することで更新処理による負荷を軽減
  120. 120. #UE4 | #gcconf2020 Invalidation Box ● 設定 CanCacheを有効にする (デフォルト有効) ● 使い方 Invalidation Boxで対象のWidget をラップ、効果はラップした対象 全てに影響
  121. 121. #UE4 | #gcconf2020 Invalidation Box 適用することで定常的なwidgetの更新コストを抑制する 適用前 適用後
  122. 122. #UE4 | #gcconf2020 Tick SlatePrepass Paint AddElement Tick SlatePrepass Paint AddElement 適用前 適用後 キャッシュを利用して処理スキップ
  123. 123. #UE4 | #gcconf2020 Global Invalidation ● 機能 (早期公開版) ● Invalidation Panelのキャッシュ効果をSlate全体に適用する機能 ● Invalidation BoxとGlobal Invalidationの併用は不可 ● レイアウト変更が生じた際にも自動的にキャッシュを無効化 ● 使い方 ● ”Slate.EnableGlobalInvalidation 1”を入力 ● PIE時は ”New Editor Window (PIE)”のみ有効
  124. 124. #UE4 | #gcconf2020 Global Invalidation ● 効果検証 単にImageを2000枚並べただけのケース
  125. 125. #UE4 | #gcconf2020 Global Invalidation Disable Enable Invalidation Panelを配置せずとも Slate全体にキャッシュ適用されてコストダウン
  126. 126. #UE4 | #gcconf2020 Global Invalidation Disable Enable 全てのBatch Elementはキャッシュされる 毎フレームのPaint処理もキャッシュによってコスト削減
  127. 127. #UE4 | #gcconf2020 Retainer Box ● 機能 Render Targetに描画して更新処理を任意にスキップする 処理 フレーム1 フレーム2 フレーム3 フレーム4 フレーム5 Retainer Box 未適用 Retainer Box 適用 RBを適用することで更新処理による負荷を軽減
  128. 128. #UE4 | #gcconf2020 Retainer Box ● 設定 5フレームの周期で、フェーズ0 (1フレーム目)で更新処理を行う場 合は右図のように設定する ● 使い方 Retainer Boxで対象のWidgetを ラップ、効果はラップした対象全 てに影響
  129. 129. #UE4 | #gcconf2020 Retainer Box 結果として下記のように, 1フレーム, 6フレーム, ...と、5フレーム毎 に更新が継続して実行されるように
  130. 130. #UE4 | #gcconf2020 リソース (Texture) Export形式 ● .png/.tgaでエクスポート、圧縮の観点から2のべき乗サイズを利用 圧縮形式 ● [UserInterface2D]は非圧縮 ● 通常は[DXT]が使用されるが用途次第で変える ● Texture Groupは[UI]を利用 アルファ ● リソースサイズが大きくなるため必要なものに限定して利用 ● 単なるフェードで半透明を適用するならWidgetの機能で可能
  131. 131. #UE4 | #gcconf2020 リソース (Texture) Texture Size ● テクスチャでメモリを占有しすぎないようにテクスチャサイズを調整 ● 小さい表示物、重要でない表示物に巨大なサイズを割り当てない Mips ● テクスチャ解像度がターゲットと一致しない場合は[No Mip Maps] ● テクスチャを縮小して使用する場合などは[From Texture Group]
  132. 132. #UE4 | #gcconf2020 ネイティブ化 Widget Blueprintをネイティブ化は効果がある...? メリット ● UObjectが減ることでロードやGC時間が改善できるが効果は実装次第 ● CPU処理はBlueprintアクセスのコストが削減されて恩恵を受ける デメリット ● ネイティブ化されたコードを含むサイズの増加 ● Widgetで発生した問題の切り分けの複雑化
  133. 133. #UE4 | #gcconf2020 ネイティブ化 変数などのUObjectは変わらず、マクロなどBPに影響 ネイティブ化前 ネイティブ化後
  134. 134. #UE4 | #gcconf2020 ウィジェットアニメーション ● 今までの課題 ● 複雑なアニメーションの高い評価コスト ● インスタンス化されたアニメーションによる長いロード ● 改善された点 ● UE4.22 : Widget Animationを共通化 ● UE4.25:UProperty → FProperty に置き換え
  135. 135. #UE4 | #gcconf2020 Button Blueprint Open Anim Press Anim Hover Anim ● 4.22以前 (オブジェクト数が多かった) ● 4.22以降 (オブジェクト数が削減された) ボタンを2つ 追加 Button Blueprint Open Anim Press Anim Hover Anim Button Blueprint Open Anim Press Anim Hover Anim Button Blueprint Open Anim Press Anim Hover Anim Button Blueprint Open Anim Press Anim Hover Anim ボタンを2つ 追加 Open Anim Press Anim Hover Anim Button BlueprintButton BlueprintButton Blueprint
  136. 136. #UE4 | #gcconf2020 Widget AnimationとUObject数の推移 アニメーション なし Class Count NumKB Total 39 11.89 Case1 :アニメーションなしの状態
  137. 137. #UE4 | #gcconf2020 Widget AnimationとUObject数の推移 1アニメーション Class Count NumKB Total 42 13.42 Case2 :アニメーション1つ追加
  138. 138. #UE4 | #gcconf2020 Widget AnimationとUObject数の推移 1アニメーション+1トラック Class Count NumKB Total 46 16.17 Case3 :アニメーション1つとTransformトラック1つを追加
  139. 139. #UE4 | #gcconf2020 Widget AnimationとUObject数の推移 アニメーションやトラックを追加するとコストが増えます
  140. 140. #UE4 | #gcconf2020 Widget AnimationとUObject数の推移 アニメーションやトラック追加時のObject数の変化 (UE4.24)
  141. 141. #UE4 | #gcconf2020 Engine VersionとUObject推移 1アニメーション+1トラック (UE4.24) Class Count NumKB Total 46 16.17 1アニメーション+1トラック (UE4.25) Class Count NumKB Total ??? ??? バージョンによる推移は?
  142. 142. #UE4 | #gcconf2020 Engine VersionとUObject推移 Object数は以前の40%削減、サイズは50%超の削減
  143. 143. #UE4 | #gcconf2020 Engine VersionとUObject推移 1アニメーション+1トラック × 1 Class Count NumKB Total 46 16.17 1アニメーション+1トラック × 10 Class Count NumKB Total ??? ??? Widget数による傾向は?
  144. 144. #UE4 | #gcconf2020 Engine VersionとUObject推移 以前に比べてWidget数が増えても Object数は54%削減、サイズは71%縮小
  145. 145. #UE4 | #gcconf2020 Engine VersionとUObject推移 Engine Versionの更新に伴うAnimation付きWidgetのObject数の変化
  146. 146. #UE4 | #gcconf2020 デバッグ ● パフォーマンス計測 ● Stats ● Unreal Insights ● 設定の確認 ● Widget Reflector ● Asset Audit ● 動作の追跡 ● Slate Debugger ● Debug Tools
  147. 147. #UE4 | #gcconf2020 デバッグ コンソールコマンド:Stat Slate ● スレートに関するパフォーマンスを計測するコマンド ● Statsを描画するコストが追加されるので目安程度に ● ただしボトルネックのポイントを特定するのに有用
  148. 148. #UE4 | #gcconf2020 Stat Slate レイアウト更新処理 ⇒ 表示物(ジオメトリ)が多い エレメント追加処理 ⇒ バッチ処理が多い
  149. 149. #UE4 | #gcconf2020 デバッグ Unreal Insights ● アプリケーションのパフォーマンスをプロファイルする ● Slate専用イベント (“Stat Slate”の対象)もキャプチャ可能
  150. 150. #UE4 | #gcconf2020 Unreal Insights レイアウト更新処理 ⇒ 表示物(ジオメトリ)が多い Tick処理 ⇒ Tickが動いているSlateが多い
  151. 151. #UE4 | #gcconf2020 デバッグ Widget Reflector ● 利用中のリソースや設定をキャプチャして解析できるツール [UE4] Widget Reflectorを使ってリソースや設定を調べよう
  152. 152. #UE4 | #gcconf2020 デバッグ Asset Audit ● アセットの情報をリスト化して確認できるツール
  153. 153. #UE4 | #gcconf2020 Asset Audit Property Bind数 ⇒ イベント駆動の方法に変更? Tick駆動予測 ⇒ 適切な稼働か?
  154. 154. #UE4 | #gcconf2020 デバッグ コンソールコマンド:SlateDebugger.Start ● フォーカスの移行、キャプチャ、入力系イベントなどの Slateイベントをログに出力
  155. 155. #UE4 | #gcconf2020 デバッグ Debug Tools ● Slateに関連する様々なデバッグ機能を提供するツール
  156. 156. #UE4 | #gcconf2020 Test Suite
  157. 157. #UE4 | #gcconf2020 関連リンク ● 公式ドキュメント UMG (Unreal Motion Graphics) のベスト プラクティス ● 公式ブログ UMG のベスト プラクティス ● 公式スライド 猫でも分かるUMG ● UE4 ANSWERHUB 情報共有:UMGミーティングの資料
  158. 158. #UE4 | #gcconf2020

×