タイトル: リストビュー (ListView)
SEOタイトル: Unreal Engine 5 ListView 完全ガイド(UMG / Entry Widget Class / IUserObjectListEntry / 動的バインド / 仮想化)
| この記事の要点 |
|
ListView とは
ListView(リストビュー)は UE5 の UMG(Unreal Motion Graphics)で提供される仮想化対応のリストウィジェットです。インベントリ、スコアボード、クエスト一覧、ロビーのプレイヤー一覧など、同じ形式の項目を縦/横に並べて表示する用途で使います。
古くからある Vertical Box / Scroll Box 内に手動で要素を作る方式と違い、ListView は画面に見える範囲だけウィジェットを生成し、スクロールで再利用するため、数千〜数万件のデータでも軽快に動作します。
ListView と類似ウィジェット
| ウィジェット | 表示形式 | 用途 |
|---|---|---|
| ListView | 縦/横の 1 列リスト | スコアボード、メッセージ一覧 |
| TileView | タイル状グリッド | インベントリ、ショップ |
| TreeView | ツリー(展開可能) | カテゴリ階層、ファイラー |
使い方の全体像
- 1 行ぶんの表示を担うEntry Widget Blueprint を作成(
UUserWidget派生) - Entry Widget にIUserObjectListEntry インタフェースを実装
- 項目データを表すUObject 派生クラスを作成(プロパティを持つ)
- 親の Widget にListView を配置し、Entry Widget Class に手順 1 のクラスを指定
- Event Construct や任意のタイミングで、Set List Items / Add Item で項目を流し込む
ステップ 1: 項目データクラス
表示する 1 件ぶんのデータを保持する UObject を作成。BlueprintReadWrite なプロパティを持たせます。
// ItemData.h
UCLASS(BlueprintType)
class MYGAME_API UItemData : public UObject
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadWrite) FString Name;
UPROPERTY(BlueprintReadWrite) int32 Quantity;
UPROPERTY(BlueprintReadWrite) UTexture2D* Icon;
};
Blueprint Only でも構いません。Object 派生の Blueprint クラスを作って同じプロパティを持たせます。
ステップ 2: Entry Widget Blueprint
1 行ぶんの見た目を作る Widget Blueprint。WBP_ItemEntry として作成し、TextBlock / Image などをデザイン。Class Settings → Implemented Interfaces に IUserObjectListEntry を追加します。
イベント実装(Blueprint)
インタフェースを追加すると On List Item Object Set イベントが呼び出せるようになります。引数の ListItemObject をデータクラスにキャストして UI に反映します。
Event On List Item Object Set
│ (Object: UObject*)
▼
Cast To ItemData
│
├ Name → Set Text (TextBlock_Name)
├ Quantity → Format Text "x{n}" → Set Text (TextBlock_Qty)
└ Icon → Set Brush from Texture (Image_Icon)
C++ 版
// WBP_ItemEntry の親 C++
UCLASS()
class MYGAME_API UItemEntryWidget
: public UUserWidget, public IUserObjectListEntry
{
GENERATED_BODY()
protected:
UPROPERTY(meta = (BindWidget)) UTextBlock* TextName;
UPROPERTY(meta = (BindWidget)) UTextBlock* TextQty;
UPROPERTY(meta = (BindWidget)) UImage* ImageIcon;
virtual void NativeOnListItemObjectSet(UObject* InObject) override
{
if (UItemData* Data = Cast(InObject))
{
TextName->SetText(FText::FromString(Data->Name));
TextQty ->SetText(FText::FromString(
FString::Printf(TEXT("x%d"), Data->Quantity)));
if (Data->Icon) ImageIcon->SetBrushFromTexture(Data->Icon);
}
}
};
ステップ 3: 親ウィジェットへ ListView を配置
親の Widget Blueprint(例: WBP_Inventory)を開き、パレットから ListView をキャンバスにドラッグ。Details パネルで:
- Entry Widget Class →
WBP_ItemEntry - Orientation → Vertical(縦並び)/ Horizontal(横並び)
- Selection Mode → None / Single / Multi など
- Item Alignment → Fill / Left / Center / Right
ステップ 4: 項目を流し込む
Blueprint
Event Construct
│
▼
For Each (ItemDataArray)
│ Loop Body
▼
Add Item (ListView, item)
C++
// 親 Widget で
TArray Items;
for (int32 i = 0; i < 50; ++i)
{
UItemData* D = NewObject(this);
D->Name = FString::Printf(TEXT("Item %d"), i);
D->Quantity = FMath::RandRange(1, 99);
Items.Add(D);
}
ListView->SetListItems(Items); // 一括差し替え
// 個別追加なら ListView->AddItem(D);
主な API
| 関数 | 用途 |
|---|---|
SetListItems(Items) | 項目を一括差し替え |
AddItem(Item) | 1 件追加 |
RemoveItem(Item) | 1 件削除 |
ClearListItems() | 全削除 |
SetSelectedItem(Item) | 選択状態にする |
GetSelectedItem() | 選択中アイテム取得 |
ScrollIntoView(Item) | 指定アイテムが見えるまでスクロール |
RequestRefresh() | 表示の再描画を要求 |
主なイベント
| イベント | タイミング |
|---|---|
| On Item Clicked | 項目クリック時 |
| On Item Double Clicked | ダブルクリック時 |
| On Item Selection Changed | 選択変更 |
| On Item Is Hovered Changed | ホバー状態変化 |
| On List Item Object Set(Entry 側) | 項目データバインド時 |
選択モード
| Selection Mode | 挙動 |
|---|---|
| None | 選択不可(表示のみ) |
| Single | 1 件のみ選択 |
| SingleToggle | 1 件のみ。再クリックで解除 |
| Multi | 複数選択可 |
仮想化の仕組み
ListView は画面に見える行ぶん + 余裕分の Entry Widget のみを生成し、スクロールに応じて再利用します。例えば 10000 件の項目があっても、生成されるウィジェットは数十個。OnListItemObjectSet が再利用時に呼ばれる前提で実装しておくのが重要です(古いデータが残らないように、全プロパティを書き直す)。
よくあるトラブル
| 症状 | 原因 / 対処 |
|---|---|
| 表示されない | Entry Widget Class 未設定 / SetListItems 呼び忘れ / 親に Size Box がない |
| 古いデータが残る | OnListItemObjectSet ですべての UI を書き直していない |
| クリックイベントが発火しない | Selection Mode が None / Entry の親が IsFocusable=false |
| スクロールが効かない | ListView 自体に高さ制限がない / Item Height 未設定 |
| 項目が UObject じゃない | UStruct や Primitive は ListView で扱えない。UObject 化する |
パフォーマンスの注意
- Entry Widget は軽量に保つ(複雑なレイアウトや高解像度画像は再生成コストが大きい)
- SetListItems と AddItem の使い分け: 全更新は SetListItems、追加だけなら AddItem
- 大量データを一気に追加する場合は1 度に SetListItems
- Texture のロードは非同期を検討
FAQ
Q: 構造体(Struct)をリスト項目にしたい
A: ListView は UObject 派生のみ。Struct を持つ UObject ラッパークラスを作って包みます。
Q: 並べ替え(ソート)したい
A: 元の TArray を並べ替えてから SetListItems で再投入します。ListView 自体にソート機能はありません。
Q: 検索フィルタを実装したい
A: 別途検索用のテキストボックスを置き、入力に応じてフィルタした配列を SetListItems で再投入します。
関連
- TileView — グリッド状のリスト
- TreeView — ツリー状のリスト
- UMG / Widget Blueprint — UI 構築
- UObject — UE のオブジェクト基底
- Scroll Box — 仮想化なしのスクロール