---
title: [Tokyo DevDays  26&#039;] UE5のUIフレームワークとUIアニメーションの解説
tags:  #ue5 #devdays  
author: [エピック ゲームズ ジャパン](https://image.docswell.com/user/EpicGamesJapan)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/GEWGNMR3J2.jpg?width=480
description: 2026年8月26日に開催されました「Unreal Engine Tokyo Dev Days 26&#039;」イベントの「UE5のUIフレームワークとUIアニメーションの解説」講演のスライドです。
published: August 31, 26
canonical: https://image.docswell.com/s/EpicGamesJapan/53JYJY-DevDays26-UI
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/GEWGNMR3J2.jpg)

UE5のUIフレームワークと
UIアニメーションの解説
Epic Games Japan
Lead Software Engineer, Developer Relations
鍬農 健⼆郎
Last update: Aug 26, 2026


# Page. 2

![Page Image](https://bcdn.docswell.com/page/47ZL3QRGJ3.jpg)

セッションのゴール
話すこと
●
UE5 の UI がどのように進化してきたか
●
プロジェクトで UI を組む際のポイント
●
UMG アニメーションに関する変更
ポイント
●
Widget単体ではなく、画⾯管理‧⼊⼒‧データまで含めてUIを設計
●
⼤規模UIで破綻しにくい構成
●
実装時の判断基準と実例


# Page. 3

![Page Image](https://bcdn.docswell.com/page/YJ6WX6RQJV.jpg)

⼤規模プロジェクトで表⾯化する問題
UE5 では⼤規模UI向けの仕組みが段階的に追加されてきた
#
⼤規模プロジェクトで起きること
問題
実現⽅法
1
対応デバイスや⼊⼒経路の追加
⼊⼒処理の競合
Action Router
2
画⾯数が膨⼤かつ複雑
画⾯遷移‧フォーカス管理が複雑化
CommonUI
3
表⽰データが増え、更新も頻繁
更新コストと、改修の波及範囲
MVVM
4
演出が増え、同時に⼤量再⽣
フレーム時間
Sequencer ECS
5
関わる⼈が増える
実装ルールの統⼀が難しくなる
MCP / Toolset


# Page. 4

![Page Image](https://bcdn.docswell.com/page/GJ5MX682J4.jpg)

1. UIのこれまで
Agenda
2. UIフレームワーク
3. UIアニメーション
4. UIのこれから


# Page. 5

![Page Image](https://bcdn.docswell.com/page/LE3WXQ81E5.jpg)

第1章
UIのこれまで


# Page. 6

![Page Image](https://bcdn.docswell.com/page/8EDK29MK7G.jpg)

UE5でのUI機能の偏移
5.0
5.1
5.2
5.3
5.4
5.5
5.6
5.7
CommonUI
Beta
CommonUI
Experimental
MVVM
Experimental
5.8
CommonUI
ProductionReady
MVVM
Beta
UMG Preview
Experimental
UIComponent
Experimental
Widget Animation
SequencePlayer
Widget Animation
Sequencer ECS
MCP/Toolset
Experimental


# Page. 7

![Page Image](https://bcdn.docswell.com/page/V7PK1ZR3J8.jpg)

UE4→UE5で何が変わったか？
Widget中⼼の構成 (UE4)
●
Widget からゲーム側のデータを直接参照
Frameworkを利⽤した構成 (UE5)
●
GetOwningPlayer() → コンポーネント → 値
●
Widget は表⽰処理を中⼼にする
表⽰データは View Model 経由で受け取る
●
OnKeyDown / SetKeyboardFocus
●
Widget が⾃分で⾒た⽬を持つ
各 WBP に⾊とフォントが直書き
Widget は渡されたデータを描くだけ
⼊⼒はフレームワークがルーティング
Activatable Tree にバインドを登録
●
⾒た⽬はアセット化されたStyle/Material
統⼀されたデザインとスタイル
Widget から⼊⼒‧画⾯管理‧データ処理を分離


# Page. 8

![Page Image](https://bcdn.docswell.com/page/2JVVYWRNJQ.jpg)

画⾯‧フォーカス
⼊⼒
データ
第2章
UIフレームワーク


# Page. 9

![Page Image](https://bcdn.docswell.com/page/5EGL9DM5JL.jpg)

画⾯‧フォーカス
Common UI
⼊⼒
データ
第2章
UIフレームワーク


# Page. 10

![Page Image](https://bcdn.docswell.com/page/4JQYW1RL7P.jpg)

CommonUI は画⾯の状態管理を引き受ける
CommonUI なし
●
パッドのボタン管理が複雑
CommonUI が提供
●
画⾯ごとに OnKeyDown を書く
●
異なるキー処理を複数画⾯に実装する
ボタンイベントをテーブルで定義、キー画像も同梱
●
キーの変更や交換に弱い
●
管理が複雑な Widget のフォーカス
ポーズメニューを開いてもキャラが動く
Activatable Widget
フォーカス管理と活性/⾮活性の概念を Widget に導⼊
●
画⾯を開いた瞬間フォーカスが迷⼦
●
Input Action の抽象化
Action Router
活性な Widget Tree 構造を持ち⼊⼒を上から順に配送
●
SetInputMode を画⾯ごとに呼ぶ
Input Conﬁg
レイヤ単位で Game / Menu / All とカーソル状態宣⾔
●
Container Stack / Queue
重ね合わせと排他をフレームワーク側で保証


# Page. 11

![Page Image](https://bcdn.docswell.com/page/K74WKR85E1.jpg)

状態管理：「表⽰中」と「アクティブ」を分離する
CommonActivatableWidget は「表⽰されている」と「今アクティブである」を分離
// Engine/Plugins/Runtime/CommonUI/Source/CommonUI/Public/CommonActivatableWidget.h
void ActivateWidget ();
// 活性化 → 入力バインドが有効になり、フォーカスが入る
void DeactivateWidget ();
// 非活性化 → 入力バインド無効表示は残せる
virtual UWidget* NativeGetDesiredFocusTarget () const; // 活性化時にどこへフォーカスするか
主要フラグ
プロパティ
意味
使いどころ
bAutoActivate
Construct 時に⾃動で活性化
HUD など常時アクティブなもの
bIsBackHandler
「戻る」⼊⼒を⾃分が処理する
画⾯ルート, NativeOnHandleBackAction() を実装
bSupportsActivationFocu
s
活性化時にフォーカスを奪うか
HUD レイヤは false にして裏でフォーカスを取らせない
bAutoRestoreFocus
復帰時に前回位置へ戻す
リスト画⾯戻ったら同じ⾏に居てほしい
注意：GetDesiredFocusTarget()未実装のActivatable Widgetは、初期フォーカス未保証で操作不能になりやすい


# Page. 12

![Page Image](https://bcdn.docswell.com/page/LJ1YXQ22EG.jpg)

画⾯遷移：Stack で表す
CommonActivatableWidgetContainerBase とその派⽣が遷移のルールを持つ
クラス
挙動
UCommonActivatableWidgetStack
後⼊れ先出し、上を閉じると下が復帰
UCommonActivatableWidgetQueue
先⼊れ先出し、1 つずつ順番に表⽰
UCommonActivatableWidgetSwitcher
排他切り替え（タブなど）
Stack が保証すること
●
●
●
push した Widget が活性化、下の Widget は⾃動的に⾮活性化、⼊⼒を受けない
pop すると下が復帰し、フォーカスも戻る
遷移アニメーション (SCommonAnimatedSwitcher ) を挟める


# Page. 13

![Page Image](https://bcdn.docswell.com/page/GJWGNMR272.jpg)

Lyra ：「1 Layout + 複数Layer」で組む
UGameUIManagerSubsystem
GameInstance サブシステムUI 全体の⼊⼝
所有
「レイアウトをどう出すか」の⽅針
UGameUIPolicy
LocalPlayer毎に⽣成
UPrimaryGameLayout
プレイヤー1⼈分の UI ルート
Layout上に複数のLayer Stackを置く
UI.Layer.Game
HUD（常時表⽰‧フォーカスを取らない）
UI.Layer.GameMenu
インベントリ等、ゲーム内メニュー
UI.Layer.Menu
フロントエンド、ポーズメニュー
UI.Layer.Modal
確認ダイアログ、エラー


# Page. 14

![Page Image](https://bcdn.docswell.com/page/4EZL3QR473.jpg)

Lyra ：画⾯を⾮同期にPushする
⼤規模 UI では WBP は 重いので、ハード参照を持たず⾮同期にロードして push
// Samples/Games/Lyra/Plugins/CommonGame/Source/Public/PrimaryGameLayout.h
template &lt;typename ActivatableWidgetT = UCommonActivatableWidget&gt;
TSharedPtr&lt;FStreamableHandle&gt; PushWidgetToLayerStackAsync (
FGameplayTag LayerName,
bool bSuspendInputUntilComplete,
// ← ロード中の入力を止める
TSoftClassPtr&lt;UCommonActivatableWidget&gt; Class,
// ← ソフト参照
TFunction&lt; void(EAsyncWidgetLayerState, ActivatableWidgetT*)&gt; StateFunc);
ポイント
●
●
●
TSoftClassPtr … UI ルートが全画⾯を参照しない
bSuspendInputUntilComplete … ロード中の連打で⼆重 push させない
EAsyncWidgetLayerState（Initialize / AfterPush / Canceled ）… 初期化時、押し込み後、を分離


# Page. 15

![Page Image](https://bcdn.docswell.com/page/Y76WX6RG7V.jpg)

⼤規模化で必要な機能はある程度⽤意されている
機能
クラス
何のために存在するか
Widget プーリング
ICommonPoolableWidgetInterface
Stack / ListView がインスタンスを使い回す
遅延画像ロード
UCommonLazyImage
TSoftObjectPtr&lt;UTexture&gt; を⾮同期ロード (遅延中はスピナー表⽰)
遅延 Widget
UCommonLazyWidget / UCommonLoadGuard
「ロード中」表現をフレームワーク化
リスト
UCommonListView / TileView / TreeView
エントリ Widget を 仮想化 + プール、インスタンスは画⾯分だけ
プラットフォーム分岐
UCommonUIVisibilitySubsystem +
UCommonHardwareVisibilityBorder
「パッド時のみ表⽰」「モバイルのみ表⽰」を Widget Tree上で宣⾔
数値表⽰
UCommonNumericTextBlock
⽤途に応じた数値表現
リッチテキスト
UCommonRichTextBlock + UCommonUIRichTextData
インラインアイコン‧スタイルをデータテーブルで⼀元管理
ポイント：これらは「便利機能」ではなく、⼤規模 UI で⾃作するものを先に⽤意してあるもの
⾃作すると CommonUI の⼊⼒‧フォーカス‧プール機構と噛み合わなくなる可能性がある


# Page. 16

![Page Image](https://bcdn.docswell.com/page/G75MX68X74.jpg)

画⾯‧フォーカス管理 の事例をさらに学ぶ
How to Handle Input and Navigation in Unreal Motion Graphics (UMG) | Unreal Fest Gold Coast 2024


# Page. 17

![Page Image](https://bcdn.docswell.com/page/9J29XMKQER.jpg)

画⾯‧フォーカス
⼊⼒
Action Router
データ
第2章
UIフレームワーク


# Page. 18

![Page Image](https://bcdn.docswell.com/page/DEY48XNYJM.jpg)

⼊⼒はどの順で流れて、消費されて、届くのか
OS
IInputDevice
FSlateApplication
Slate Widget Tree
UCommonViewportClient
UCommonUIActionRouterBase
FUIActionBinding
コントローラ‧⼊⼒デバイス毎の実装
InputPreProcessor チェーン、ここで⼊⼒判定可能
フォーカスされたSWidgetに配送、UMGが⼊⼒握り潰す場所
Viewport が⼊⼒を補⾜
UI ⼊⼒の中枢、最前⾯レイヤから順にアクションを照合
登録済みアクション実⾏、⼀致したら OnExecuteAction 実⾏


# Page. 19

![Page Image](https://bcdn.docswell.com/page/VJNYQ1XR78.jpg)

Action Router が Active Widget への⼊⼒を管理する
FCommon
InputActionDataBase
DataTable·Key/Icon/ Hold
UCommon
ActivatableWidget
Activate + RegisterUIActionBinding
FUIActionBinding
実⾏時マッピング
UCommon
UIActionRouterBase
UCommon
GameViewportClient
ハブ
⼊⼒の⼊⼝
FUIInputConﬁg
Menu / Game / Al
●
Action Router は Local Player 単位で UI Action Binding を管理
○ 押されているキーを今開いている画⾯に届ける
○ 画⾯の開き⽅に併せて届き先を⾃動で切り替える
●
内部では活性な Activatable Widget をTreeとして持つ
○ ZOrderとレイヤを⾒て 最前⾯のルートから⼊⼒を配る
○ Active な Activatable Widget Tree を基に⼊⼒先を決定する


# Page. 20

![Page Image](https://bcdn.docswell.com/page/YE9PD58ZJ3.jpg)

Input Conﬁg で Game/UI の⼊⼒モードを設定する
FCommon
InputActionDataBase
FUIActionBinding
DataTable·Key/Icon/ Hold
UCommon
ActivatableWidget
実⾏時マッピング
UCommon
UIActionRouterBase
UCommon
GameViewportClient
ハブ
⼊⼒の⼊⼝
FUIInputConﬁg
Activate + RegisterUIActionBinding
Menu / Game / Al
ECommonInputMode
意味
ユースケース
Game
⼊⼒はゲームだけが受け取る
HUD 表⽰中の通常プレイ
Menu
⼊⼒は UI だけが受け取る
フルスクリーンメニュー、モーダル
All
両⽅が受け取る
ミニマップ拡⼤、インゲームのマップ画⾯
推奨：Input Conﬁg は 画⾯ごとに書かない、Layer / Activatable Widget 単位で Input Conﬁg を定義


# Page. 21

![Page Image](https://bcdn.docswell.com/page/GE8D3YZYED.jpg)

Common UIとEnhanced Input はどう分担するか？
これまで（〜5.7）
●
●
Common UI の UI アクションは UInputAction を直接バインドできる
⼀⽅で従来の DataTable ⽅式も現役
ただし「ゲーム⼊⼒」と「UI ⼊⼒」はビューポート層で排他的に切り分けられていた
現状（5.8〜）
●
●
●
未消費の UI ⼊⼒を Enhanced Input へ渡せるようになる
ゲーム側の抑制は IMC の GameplayTag でフィルタ
5.8 では ⻑押し⼊⼒（ホールド）系の修正、1 アクションへの追加キーバインド等も追加
CommonUI.AlwaysWaitForHoldActionToComplete ,
CommonUI.bEnhancedInputDynamicallyResolveHoldKeysForInputAction


# Page. 22

![Page Image](https://bcdn.docswell.com/page/LELMV4D97R.jpg)

Player Input Debugger で⼊⼒イベントを確認


# Page. 23

![Page Image](https://bcdn.docswell.com/page/4JMYGKPVJW.jpg)

画⾯‧フォーカス
⼊⼒
データ
MVVM (Model View ViewModel)
第2章
UIフレームワーク


# Page. 24

![Page Image](https://bcdn.docswell.com/page/PJR9ZX1W79.jpg)

更新は「毎フレーム」から「変更時のみ」へ
Property Binding
●
●
●
コストが UI の複雑さに正⽐例
Blueprint 関数呼び出しのオーバーヘッドが乗る
「いつ更新されるか」がコード上に現れない
Event Tick で更新
●
●
●
Widget が ゲームロジックを知ってしまう
値が変わらなくても更新を呼び Invalidate
Widget を消すとロジックも消える
MVVM： 変わったときだけ、変わったところだけ 更新
●
●
ViewModel のプロパティが変化 → その値に依存するバインドだけが実⾏される
Widget 数が増えても、コストは「実際に変化した値の数」にしか⽐例しない


# Page. 25

![Page Image](https://bcdn.docswell.com/page/PEXQ96YVJX.jpg)

FieldNotifyが「変わった」を伝える
MVVM の下には、UMG から独⽴した FieldNotification モジュールがある
UCLASS()
class UPlayerStatusViewModel : public UMVVMViewModelBase
{
GENERATED_BODY ()
public:
// 値が変わったときだけ BroadcastFieldValueChanged を呼ぶマクロ
void SetHealth (float In) { UE_MVVM_SET_PROPERTY_VALUE (Health, In); }
// 派生値も「通知される関数」にできる（キャッシュ不要）
UFUNCTION (BlueprintPure, FieldNotify)
float GetHealthPercent () const { return MaxHealth &gt; 0.f ? Health / MaxHealth : 0.f; }
private:
UPROPERTY (BlueprintReadWrite, FieldNotify, Setter, Getter, meta=(AllowPrivateAccess))
float Health = 0.f;
};


# Page. 26

![Page Image](https://bcdn.docswell.com/page/3EK9P135ED.jpg)

変更通知から描画まで、何が起きるのか
ゲーム側
FieldNotify
UMVVMView
Execution Mode
Conversion
View
Slate
次のPaint
ViewModel-&gt;SetHealth(80.f)
FieldId でフィルタされた delegate のみ発⽕
このフィールド依存の「コンパイル済みバインディング」を引く
即時実⾏/フレーム末にまとめて実⾏ を判定
ﬂoat → FText などの変換関数を適⽤
UTextBlock::SetText(...)など、Widget の通常の Setter
Invalidate → 次の Paint で反映
ここまでが1回の更新


# Page. 27

![Page Image](https://bcdn.docswell.com/page/L73WXQG175.jpg)

更新タイミングは「回数」を減らすために選ぶ
EExecutionMode
挙動
使いどころ
Immediate
ソース値が変わった 瞬間 に実⾏
単発‧低頻度⼊⼒への即応が要る箇所
Delayed
変わったら フレーム末（描画前）に 1 回 実⾏
1 フレームに複数回変わる値、連続ダメージ等
Tick
変化に関わらず 毎フレーム 実⾏
原則使わない（Property Binding と同コスト）
Auto
複数Fieldから起動時 Delayed/単⼀なら Immediate
既定値、基本これ
●
●
●
●
既定（Auto）から動かさない
Tick を選ぶ理由はほぼ無い
フレーム中に何度も変わる値は 明⽰的に Delayed
順序依存で値が壊れるときも Delayed で直ることがある


# Page. 28

![Page Image](https://bcdn.docswell.com/page/87DK291KJG.jpg)

Widget は View Model の取得⽅法を知らなくてよい
BlueprintViewModelContextCreationType
概要
向いている場⾯
Manual
コードから SetViewModel() で差し込む
親 Widget が⼦に配るリストのエントリ
Create Instance
Widget が⾃分⽤に new する
その Widget 専⽤の状態（開閉状態など）
Global View Model Collection
名前付きコレクションから取得
⼿軽だが ⽂字列キー依存乱⽤注意
Property Path
既に持っている VM の⼦ VM を辿る
VM の⼊れ⼦（&quot;VM-ception&quot;）
Resolver
UMVVMViewModelContextResolver が取得/⽣成
グローバルに 1 つだけ存在する VM
主に使う 2 つ
●
●
Manual … ⽂脈から取れるとき（親→⼦）
Resolver … グローバル VM を取るとき
Resolver を勧める理由
●
取得ロジックが C++ の 1 クラスに閉じる
Widget 側は「この VM が欲しい」と宣⾔するだけ


# Page. 29

![Page Image](https://bcdn.docswell.com/page/VJPK1ZQ3E8.jpg)

MVVMを使う場所‧使わない場所を決める
向いているもの
●
状態を持つ画⾯
気をつけること
●
まだ Beta（5.8 時点）
●
誰が所有するか、VMの寿命を決めて作成
メニュー、インベントリ、ストア、設定
●
同じデータを複数箇所で表⽰する HUD
●
テーマ / スタイルガイドの供給
⾊‧マテリアル‧⽂⾔を VM から配ると、季節ごとの着せ
替えが VM 差し替えだけで済む
●
ListView のエントリ
UMVVMViewListViewBaseClassExtension が対応


# Page. 30

![Page Image](https://bcdn.docswell.com/page/2EVVYW5NEQ.jpg)

MVVM の事例をさらに学ぶ
Powering Dynamic UI with Viewmodels | Unreal Fest Orlando 2025


# Page. 31

![Page Image](https://bcdn.docswell.com/page/57GL9D65EL.jpg)

2 章まとめ：Widgetから「⼊⼒/画⾯状態/データ」を外した
問題
UE5の実装
Widget からの移譲
画⾯が多いと遷移とフォーカスが管理しきれない
CommonUI
どの画⾯が今アクティブかという状態
デバイスが増えると、⼊⼒が競合する
Action Router
今どこが⼊⼒を受けるかという所有権
データが増え、更新が頻繁になると、改修が波及する
MVVM
何を表⽰するかという判断
「便利な機能が増えた」のではなく「Widget 側で実装する必要があった仕組みに移した」
Widget が単純になるほど、画⾯を増やすコストは枚数に⽐例しなくなる


# Page. 32

![Page Image](https://bcdn.docswell.com/page/4EQYW14LJP.jpg)

第3章
UIアニメーション


# Page. 33

![Page Image](https://bcdn.docswell.com/page/KJ4WKRQ571.jpg)

まずUIアニメーションの⼿法を選ぶ
UI を動かす⽅法は 4 つ、まずどれを使うかの判断が性能の殆どを左右する
⼿法
利⽤ケース
コスト
使いどころ
Widget Animation
タイムライン、複数プロパティの同期
中
画⾯のIn/Out、ボタン反応、演出全般、等
Material
連続的な視覚効果、複数Widgetの⾒た⽬同期
⼩
常時ループする装飾、ホバー光沢、等
Niagara
瞬間的に豪華な演出、視線誘導
⾼
視線誘導、重要ボタン、等
Tick / Timer
何でもできる
⾼
原則使わない
推奨：⾒た⽬の &quot;連続的な変化&quot; は Material、&quot;状態の遷移&quot; は Widget Animation


# Page. 34

![Page Image](https://bcdn.docswell.com/page/LE1YXQP27G.jpg)

Material を主体としてアニメーションを作成
メリット
●
ボタン選択状態等をマテリアル内で表現
デメリット
●
Widget 階層が浅くなる
●
⾊‧⾓丸‧グラデーションをパラメータ化
命令数はプラットフォームによっては重い
特にモバイル、全画⾯を覆う UI マテリアルは要注意
●
ベースマテリアルの変更の影響範囲が巨⼤
●
アーティストにマテリアルグラフの理解を要求
テーマ変更が パラメータの差し替えだけ
●
レイヤ数と Widget 数が減る
ドローコールが減る
●
実⾏時にパラメータを動かせる
アニメーションもマテリアルで完結
Epic では bitmap を極⼒使わず、UIの⾒た⽬をマテリアルで作成


# Page. 35

![Page Image](https://bcdn.docswell.com/page/GEWGNM22J2.jpg)

Widget Animation は Sequencer
Widget Animation は、 Widget Blueprint の中に埋め込まれた MovieSceneSequence
WBP_MainMenu (WidgetBlueprintGeneratedClass)
└─ UWidgetAnimation &quot;Anim_Intro&quot;
├─ UMovieScene
└─ FWidgetAnimationBinding
← UMovieSceneSequenceを継承
← Track/Section/Key
← どのWidgetを動かすか
重要な性質
●
●
Track / Section / Key は MovieScene として保持
Widget Animation の評価基盤は Sequencer と共通


# Page. 36

![Page Image](https://bcdn.docswell.com/page/47ZL3QD4J3.jpg)

UE5.6で「再⽣状態」の持ち⽅が変わった
●
●
●
⼀⾔でいうと「再⽣するアニメーション1本ごとに UObject を作る」ことを⽌めた
Widget Animation の評価処理が Entity System ベースへ移⾏
5.6 以降にアップデートしたら何もせずにこれを使⽤している


# Page. 37

![Page Image](https://bcdn.docswell.com/page/YJ6WX61GJV.jpg)

UObjectPlayer から軽量な Animation State へ
〜5.5：UUMGSequencePlayer
5.6〜：FWidgetAnimationState
UPROPERTY(Transient)
TArray&lt;TObjectPtr&lt;UUMGSequencePlayer&gt;&gt;
ActiveSequencePlayers;
TArray&lt;TObjectPtr&lt;UUMGSequencePlayer&gt;&gt;
StoppedSequencePlayers;
TArray&lt;TSharedRef&lt;FWidgetAnimationState&gt;&gt;
ActiveAnimations;
●
●
●
●
再⽣のたびに UObject を NewObject
IMovieScenePlayer を持つ重いインタフェース
GC の対象停⽌後も次の GC まで残る
再⽣/停⽌が多い UI で UObject 数が跳ね上がる
●
●
●
ただの struct（TSharedFromThis）
Objectなので GC対象外‧アロケーションが軽い
旧 API 互換がある


# Page. 38

![Page Image](https://bcdn.docswell.com/page/GJ5MX64XJ4.jpg)

それでも Legacy Player が残るケースがある
// Engine/Source/Runtime/UMG/Public/Blueprint/UserWidget.h
enum class ERequiresLegacyPlayer : uint8 { AutoDetect, Yes, No };
// AutoDetect （既定）… ネイティブ C++ の子がいる場合はレガシー Player を作る
virtual ERequiresLegacyPlayer GetLegacyPlayerRequirement () const;
● Legacy Player が作られることがある
⼀部トラック（旧 Event Trackなど）はまだ ECS 化されておらず、 Legacy Player を要求する
LogMovieScene: Initializing a legacy player for sequence
● 対処
Event Track → Event Repeater Track に置き換える、⼿動アップグレードが必要
5.6 以降に移⾏したら、まず「レガシー Player が作られている WBP」を洗い出す


# Page. 39

![Page Image](https://bcdn.docswell.com/page/9E29XMVQ7R.jpg)

これで Widget Animation は軽くなった？
効果的なケース
●
同じ Widget を⼤量に並べて⼀⻫に再⽣
あまり効果がないケース
●
ListView エントリ、インベントリグリッド、スコアボード
●
短いアニメーションを⾼頻度で再⽣‧停⽌
Player の⽣成コストがそもそも問題になっていない
●
ダメージ表⽰、通知、ヒットマーカー
●
複数レイヤの Intro / Outro が重なる
常時 1〜2 本しか再⽣していない
ボトルネックが Invalidation 側にある
Padding や Size を動かしているケースでは全く効果なし
●
ボトルネックが描画側にある
メニューを開きながら HUD が引っ込む、など
オーバードロー、テクスチャ、マテリアル命令数
再⽣数に⽐例してObject⽣成とGC負荷が追加
1フレーム分の評価コストには影響なし
軽くなったのは「再⽣を始めるコスト」で、速くならない場合は負荷が別のところにある


# Page. 40

![Page Image](https://bcdn.docswell.com/page/D7Y48X3YEM.jpg)

Widget Animation のコストは「何を動かしたか」
真のコストは 「変更するものとそれに伴う更新」
変更する内容
発⽣する Invalidation
相対コスト
Render Opacity / Color and Opacity
Paint のみ
最⼩、再 Paint だけ
Material Parameter
ほとんどなし
最⼩、GPU 側
Render Transform
Layout | RenderTransform
⼩、desired size が変わらず
Slot Position / Size / Padding / Margin
Layout
⼤、desired size が変わる
Visibility
Visibility （Layout を含む）
⼤
⼦の追加‧削除
ChildOrder （Prepass + Layout）
最⼤
推奨：動かすなら Render Transform と Opacity
例：スライドイン演出は Position ではなく Render Transform を動かして作成
Position の変更 は desired size を変えるので、兄弟 Widget (同じPanelの別 Widget ) まで再配置される


# Page. 41

![Page Image](https://bcdn.docswell.com/page/VENYQ1VRJ8.jpg)

Render Transform の変更も90%削減
https://github.com/EpicGames/UnrealEngine/commit/00f57f935256356bﬀc5ﬀc20af4b77e6bcf6eaf


# Page. 42

![Page Image](https://bcdn.docswell.com/page/Y79PD56ZE3.jpg)

キャッシュはアニメーションと相性が良くない
Global Invalidation
Retainer Box
●
配下のWidgetをRender Target にキャッシュ
●
5.8 時点でも 既定は false
●
更新頻度を落とす（Nフレーム/回だけ再描画）
●
●
更新頻度低下によりアニメーションもカクつく
有効にすると Slate 全体が Fast Path で動き、
変化した Widget だけを再描画する
●
ただし Volatile な Widget が多いと効果が薄い
推奨：①プロパティ⾒直し → ②Widget 数を減らす → ③Retainer → ④Invalidation
①②で解決しない問題は、③④でも解決しないことが多い


# Page. 43

![Page Image](https://bcdn.docswell.com/page/G78D3YPY7D.jpg)

最適化する前に評価と計測
パフォーマンスの評価で使⽤
●
●
●
●
stat Slate
… Slate 全体の負荷
stat MovieSceneEval … Sequencer 評価全体のコスト
stat MovieSceneECS … Sequencer Entity System 側の評価
Unreal Insights の Slate Insights
Widget Animation の調整で使⽤
CVar
既定
効果
UMG.AnimationBudgetMs
0.0
1フレーム中の全Anim評価時間予算(ms) 超過分は次フレームへ繰り越し
UMG.FlushAnimationsAtEndOfFrame
1
フレーム末に未処理の評価をフラッシュ/次フレームまで遅延
Widget.MaxAnimationLatentActions
100
1 フレームに実⾏する Latent アクションの上限


# Page. 44

![Page Image](https://bcdn.docswell.com/page/L7LMV419JR.jpg)

UI Performance / Invalidation の事例をさらに学ぶ
UI Performance &amp; Invalidation Debugging | Unreal Fest Chicago 2026


# Page. 45

![Page Image](https://bcdn.docswell.com/page/4EMYGKWVEW.jpg)

3 章まとめ：UIアニメーション の負荷は分けて考える
●
UIアニメーションは Material で作成、状態遷移や時間ベースは Widget Animation
●
Widget Animation は UE5.6 以降で軽量になった
○
しかし本当のコストは変更するプロパティと数に⼤きく依存
○
プロパティが影響する Invalidation を理解して使⽤する


# Page. 46

![Page Image](https://bcdn.docswell.com/page/PER9ZXYWJ9.jpg)

第4章
UIのこれから


# Page. 47

![Page Image](https://bcdn.docswell.com/page/P7XQ96GVEX.jpg)

UE5.8 で 追加された MCP プラグイン
LLMをUnreal Editorに接続して、LLMからEditorを制御することができる


# Page. 48

![Page Image](https://bcdn.docswell.com/page/37K9P1457D.jpg)

Widget や View Model を操作が可能
「ViewModel を作って、Widget にバインドを張って、コンパイルする」をプロンプト⼊
⼒から実⾏する、といったこともできる
UMGToolSet（Experimental / Editor 専⽤）
CreateWidgetBlueprint / AddWidget /
RemoveWidget
MoveWidget / RenameWidget / WrapWidgets
SetNamedSlotContent / GetNamedSlots
GetWidgets / GetWidgetDescription /
GetWidgetTreeDepth
ListWidgetClasses / GetWidgetClassInfo
AddUIComponent / RemoveUIComponent /
MoveUIComponent
ReplaceWidgetWithTemplate /
ReplaceWidgetWithChild
BindToEventProperty / ToggleWidgetAsVariable
CompileWidgetBlueprint
MVVMToolset
CreateViewModel
AddViewModelProperty
ListViewModels / ListWidgetViewModels
AddViewModelToWidget
CreateViewBinding / RemoveWidgetViewBinding
ListWidgetViewBindings
ListConversionFunctions


# Page. 49

![Page Image](https://bcdn.docswell.com/page/LJ3WXQL1J5.jpg)

Widget Blueprint (UEFN)
●
●
MVVM経由でデータをやり取りすることが前提
コンポーネント化などによるWidgetとの分離


# Page. 50

![Page Image](https://bcdn.docswell.com/page/8JDK29NKEG.jpg)

まとめ
Widget は「表⽰」だけに役割を分離し、機能と役割を適切に分離
表⽰データ
View Model
⼊⼒の所有権
画⾯の状態
Action Router
Common UI
Widget
Layout / Visual
時間/アニメーション
Sequencer


# Page. 51

![Page Image](https://bcdn.docswell.com/page/VEPK1Z5378.jpg)

Thank


# Page. 52

![Page Image](https://bcdn.docswell.com/page/27VVYWPN7Q.jpg)

依存する値はすべて Binding に⾒せる
やりがちな実装
正しい実装：Conversion Function
bIsPassCompleted にだけバインドした関数の中で、
必要な値を全部 ⼊⼒引数にする
残り 2 つの値を Blueprint の Get ノードで取る
Binding: [VM.bIsPassCompleted] →
Fn_UpdateStatus()
Fn_UpdateStatus(bIsPassCompleted):
Get VM.bIsPageCompleted
← バインドされていない
Get VM.bIsLocked
← バインドされていない
→ bIsPassCompleted が変わったときしか呼ばれない
→ ページのロックが解除されても表⽰が更新されない
Fortnite で実際にバグの原因になった、と講演で紹介されている例
Binding: [VM.bIsPassCompleted]
[VM.bIsPageCompleted] →
CF_GetActiveWidget() → SetActiveWidget
[VM.bIsLocked]
●
●
●
3 つの どれが変わっても 呼ばれる
引数として渡るので 必ず最新値
関数は Pure + Const にする
= 「Widget の状態を変えない」という契約
●
値を返す（関数内で SetActiveWidget しない）


# Page. 53

![Page Image](https://bcdn.docswell.com/page/5JGL9DP57L.jpg)

ViewModelは「画⾯」ではなく「データの責務」で分ける
分割の指針
●
1 画⾯ 1 VM にしない
関連するデータのまとまりで割る
例：SeasonPassCategoryVM/ ItemDetailsVM /
SeasonPassSelectionVM
▲
▲
│
│
[タイル一覧 ]
[詳細パネル ]
│
│
選択を書く
選択を読む
SeasonPassSelectionVM
●
VM は Widget に紐づけない
複数の Widget が同じ VM を⾒る
●
機能固有の情報を汎⽤ VM に混ぜない
ItemDetailsVM にシーズンパス固有データを⼊れない →
ショップでも使える
●
選択状態も VM に置く
→ Widget 同⼠が直接通信しなくなる（下図）
Widget 間の直接参照 = ゼロ
到達点
「バトルパス画⾯」「OG パス画⾯」「⾳楽パス画⾯」
「LEGO パス画⾯」はすべて同じ 1 つの Widget
違いは 流し込む VM のデータだけ
→ バグ修正‧演出改善が 1 箇所で全画⾯に効く


# Page. 54

![Page Image](https://bcdn.docswell.com/page/47QYW12LEP.jpg)

MVVM へ処理をすべて移⾏するべきか？
共有される状態は View Model へ、⾒た⽬だけの状態は Widget に残す
状況
Direct / Event
MVVM
⼀時的なWidget内部状態
〇
△
ゲームデータ表⽰
△
〇
複数Widgetで共有
✕
〇
頻繁に更新
△
〇
単発の簡単なUI
〇
△


# Page. 55

![Page Image](https://bcdn.docswell.com/page/KE4WKRL5J1.jpg)

Common UI を使うなら Common UI で管理を統⼀
よくある認識
●
UUserWidget/UCommonActivatableWidget 混在
正攻法
●
Widget Rootは必ず UCommonActivatableWidget
●
出し⼊れは 必ず Layer への push / pop
ActionRouter の持つ状態と⾷い違う
●
フォーカスは GetDesiredFocusTarget() で表現
AddToViewport()で Activatable Widget を直接出す
●
HUDレイヤは bSupportsActivationFocus=false
●
UCommonGameViewportClient を設定で必ず指定
混ざった瞬間フォーカス管理が複雑化
●
●
SetKeyboardFocus() を⾃分で呼ぶ
Stack を経由しないので⾮活性化されない
●
HUD で bSupportsActivationFocus=true のまま
メニューを開いてもフォーカスが HUD に吸われる
これを忘れると⼊⼒が CommonUI に届かない


