ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
2 種類のマウス操作 UI
Unreal Engine の UMG で「マウスで動かす UI」を作る方法は大きく 2 つあります:
| シンプル移動 | 正式ドラッグ&ドロップ | |
|---|---|---|
| 用途 | ウィジェット自身が動く | UI 間でアイテム移動 |
| 主な API | OnMouseButtonDown/Move/Up | DetectDragIfPressed + DragDropOperation |
| ペイロード | なし | Operation オブジェクトで運ぶ |
| 視覚フィードバック | 自前 | Drag Visual ウィジェットで自動 |
| 難易度 | 中 | やや高 |
シンプル移動: ウィジェットをドラッグ
Windowsアプリのウィンドウのように、ウィジェット自身をマウスで掴んで動かす実装です。
Blueprint 実装
[User Widget (例: WBP_DraggableWindow)]
変数:
bIsDragging (Boolean)
DragOffset (Vector2D)
[OnMouseButtonDown] override
Input: MyGeometry, MouseEvent
- IsLeftMouseButtonDown? → true
- bIsDragging = true
- DragOffset = MouseEvent.GetScreenSpacePosition - MyGeometry.GetAbsolutePosition
- Return Handled() / Capture Mouse
[OnMouseMove] override
- if bIsDragging
- NewPos = MouseEvent.GetScreenSpacePosition - DragOffset
- SetPositionInViewport(NewPos) ← Self
- Return Handled
[OnMouseButtonUp] override
- bIsDragging = false
- Return Handled / Release Mouse Capture
C++ 実装
// UDraggableWindow.h
UCLASS()
class MYGAME_API UDraggableWindow : public UUserWidget
{
GENERATED_BODY()
protected:
virtual FReply NativeOnMouseButtonDown(
const FGeometry& InGeometry,
const FPointerEvent& InMouseEvent) override;
virtual FReply NativeOnMouseMove(
const FGeometry& InGeometry,
const FPointerEvent& InMouseEvent) override;
virtual FReply NativeOnMouseButtonUp(
const FGeometry& InGeometry,
const FPointerEvent& InMouseEvent) override;
bool bIsDragging = false;
FVector2D DragOffset;
};
// UDraggableWindow.cpp
FReply UDraggableWindow::NativeOnMouseButtonDown(
const FGeometry& Geo, const FPointerEvent& Ev)
{
if (Ev.GetEffectingButton() == EKeys::LeftMouseButton)
{
bIsDragging = true;
DragOffset = Ev.GetScreenSpacePosition() -
Geo.GetAbsolutePosition();
return FReply::Handled().CaptureMouse(TakeWidget());
}
return FReply::Unhandled();
}
FReply UDraggableWindow::NativeOnMouseMove(
const FGeometry& Geo, const FPointerEvent& Ev)
{
if (bIsDragging)
{
FVector2D NewPos = Ev.GetScreenSpacePosition() - DragOffset;
SetPositionInViewport(NewPos, /*bRemoveDPIScale=*/false);
return FReply::Handled();
}
return FReply::Unhandled();
}
FReply UDraggableWindow::NativeOnMouseButtonUp(
const FGeometry& Geo, const FPointerEvent& Ev)
{
bIsDragging = false;
return FReply::Handled().ReleaseMouseCapture();
}
正式なドラッグ&ドロップ(インベントリ等)
アイテムスロット間でアイコンをドラッグして移動する場合は、Unreal 標準の Drag-and-Drop システムを使います:
手順1: DragDropOperation 派生クラスを作る
[Blueprint Class > DragDropOperation 派生]
名前: BPDDO_Item
変数を追加:
PayloadItemID (Name)
PayloadIcon (Texture2D)
SourceSlot (UserWidget Reference)
手順2: ドラッグ元のウィジェットで Detect
[InventorySlot WBP]
[OnMouseButtonDown]
Input: MouseEvent
→ Detect Drag if Pressed (Pointer Event, Key=Left Mouse Button)
→ Return Handled
[OnDragDetected]
Input: MouseEvent
- Create Widget (W_DragVisual) ← 半透明のアイコン
- Create DragDropOperation (Class = BPDDO_Item)
- PayloadItemID = この slot の ItemID
- PayloadIcon = この slot の Texture
- SourceSlot = Self
- Default Drag Visual = W_DragVisual
- Pivot = Center Center
- Return Operation
手順3: ドロップ先で受け取る
[InventorySlot WBP / 他の Slot]
[OnDrop]
Input: Operation
- Cast to BPDDO_Item
- if Success:
- 自スロットに Operation.PayloadItemID を設定
- SourceSlot を空に
- Return: true (成功扱い)
[OnDragEnter] / [OnDragLeave] でハイライト切り替え
位置の反映: 3 つの方法
| 方法 | 使い所 |
|---|---|
SetPositionInViewport(NewPos) | UserWidget 全体を動かす(Add to Viewport で追加した物) |
Set Render Translation | 軽量な見た目だけの移動。レイアウト計算非対象 |
親 Canvas Panel Slot の Position | Canvas Panel 配下の子の位置移動 |
マウス位置の取得 API
// PlayerController から
APlayerController* PC = GetWorld()->GetFirstPlayerController();
float MouseX, MouseY;
PC->GetMousePosition(MouseX, MouseY);
// ビューポート座標 (UMG 用、DPI スケール考慮)
FVector2D MousePos;
UWidgetLayoutLibrary::GetMousePositionOnViewport(this, MousePos);
// DPI スケールも考慮
FVector2D ScaledMousePos =
UWidgetLayoutLibrary::GetMousePositionScaledByDPI(PC);
// Geometry の Local 座標
FVector2D LocalPos = InGeometry.AbsoluteToLocal(
InMouseEvent.GetScreenSpacePosition());
入力モードの設定(重要)
マウスイベントが UMG に届くには、PlayerController の入力モードが適切でないといけません:
// Pause メニュー等
FInputModeUIOnly UIOnly;
UIOnly.SetWidgetToFocus(MyWidget->TakeWidget());
PlayerController->SetInputMode(UIOnly);
PlayerController->bShowMouseCursor = true;
// HUD でゲーム入力もマウスも両方
FInputModeGameAndUI GameAndUI;
GameAndUI.SetWidgetToFocus(MyWidget->TakeWidget());
GameAndUI.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
GameAndUI.SetHideCursorDuringCapture(false);
PlayerController->SetInputMode(GameAndUI);
// 通常プレイ
FInputModeGameOnly GameOnly;
PlayerController->SetInputMode(GameOnly);
PlayerController->bShowMouseCursor = false;
Z-Order とフォーカス
- 複数 Widget を重ねた時は
AddToViewport(ZOrder)の Z 値で前後関係指定 - Z が大きいほど手前
- Pause メニューは Z=1000 など大きめにすると HUD より前に出る
- マウスホバーが裏のウィジェットに届かないようにVisibility = Visible(または Self Hit Test Invisible でクリックを下に貫通)
Visibility の使い分け
| Visibility | マウスイベント |
|---|---|
| Visible | 受け取る |
| Hit Test Invisible | 受け取らない(自分も子も) |
| Self Hit Test Invisible | 自分は受けないが子は受ける |
| Hidden | 非表示・受けない・スペース確保 |
| Collapsed | 非表示・受けない・スペース不要 |
FAQ
Q: OnMouseButtonDown が呼ばれない
A: ① Visibility = Hit Test Invisible になっていないか、② 入力モードが Game Only になっていないか、③ 親ウィジェットが先にイベントを Handle していないか を確認。
Q: ドラッグ中にマウスがウィジェットから外れると追従が止まる
A: FReply::Handled().CaptureMouse(TakeWidget()) でマウスキャプチャを取得。終了時に ReleaseMouseCapture()。
Q: マウス座標がずれる
A: DPI スケールを考慮していない可能性。GetMousePositionScaledByDPI を使うか、SetPositionInViewport の第二引数 bRemoveDPIScale を false に。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- UE5のEvent Tickノードの使い方|毎フレーム処理とDelta Seconds 2026-06-13 13:26:37
- UE5のレベルブループリントでキャラクターをスポーンさせる方法 2026-06-13 13:26:37
- UE5でAI Move ToがBlockedで失敗する原因と対処方法|NavMesh確認 2026-06-13 13:26:36
- UE5のビューポートの使い方|視点操作・ビューモード・投影の基本 2026-06-13 13:26:36
- Reactのよくあるエラーと対処まとめ|環境構築・npm関連 2026-06-13 13:26:36
- UE5のWorld Compositionとは|サブレベルによる大規模ワールドと非推奨化 2026-06-13 13:26:35
- C++のコンパイルと実行方法|g++の使い方とオプション 2026-06-13 13:26:35
- .protoのgo_packageオプションとは|Goコード生成時のパッケージ指定 2026-06-13 13:26:34
- C++の開発環境構築|コンパイラとIDEの選び方・Hello World 2026-06-13 13:26:34
- gRPCクイックスタート|.proto定義からサーバ・クライアント実装まで 2026-06-13 13:26:33
- C++の関数まとめ|標準入出力(printf・cout・cin)と関数の基本 2026-06-13 13:26:33
- C#・Visual Studioのよくあるエラーと対処まとめ 2026-06-13 13:26:33
- UE5のアウトライナーとは|アクターの一覧・整理・親子付け 2026-06-13 13:26:32
- UE5でSet Input Mode UI Onlyを解除する方法|Game Onlyに戻す 2026-06-13 13:26:32
- UE5エディタの自動保存の頻度を変更する方法|Auto Save設定 2026-06-13 13:26:31
コメントを削除してもよろしいでしょうか?