要调用 中带有 “输入模式设置” 的 UI 加载功能,核心是先获取
UUMGManager 实例(通常挂载在
UUMGManager 中,确保全局可访问),再调用
UMyGameInstance 接口。以下是完整的调用流程,覆盖 C++ 代码调用 和 蓝图调用 两种场景,同时包含常见扩展需求(如指定输入模式、隐藏 UI 恢复输入)。
LoadAndShowWidget
一、前提:确保 UUMGManager 实例全局可访问
首先需要在 中存储
UMyGameInstance 实例(全局单例),这样任何地方都能通过
UUMGManager 获取管理器。如果之前未配置,需先补充以下步骤:
GameInstance
1. 修改 UMyGameInstance.h(声明管理器变量)
cpp
运行
#pragma once
#include "CoreMinimal.h"
#include "Engine/GameInstance.h"
#include "UMGManager.h" // 包含 UUMGManager 头文件
#include "MyGameInstance.generated.h"
UCLASS()
class PROJECT_API UMyGameInstance : public UGameInstance
{
GENERATED_BODY()
public:
// 游戏启动时初始化 UUMGManager
virtual void Init() override;
// 获取 UUMGManager 实例(全局访问接口)
UFUNCTION(BlueprintCallable, Category = "UI Management") // 支持蓝图调用
UUMGManager* GetUMGManager() const { return UMGManagerInstance; }
// (可选)存储当前 PlayerController,供管理器 fallback 使用
TWeakObjectPtr<APlayerController> CurrentPC;
private:
// UUMGManager 实例(全局唯一)
UPROPERTY()
UUMGManager* UMGManagerInstance;
};
2. 修改 UMyGameInstance.cpp(初始化管理器)
cpp
运行
#include "MyGameInstance.h"
#include "UMGManager.h"
#include "GameFramework/PlayerController.h"
void UMyGameInstance::Init()
{
Super::Init();
// 创建 UUMGManager 实例
UMGManagerInstance = NewObject<UUMGManager>();
if (UMGManagerInstance)
{
UE_LOG(LogTemp, Log, TEXT("UMyGameInstance: UUMGManager 初始化成功"));
}
else
{
UE_LOG(LogTemp, Error, TEXT("UMyGameInstance: UUMGManager 创建失败"));
}
}
3. 绑定默认 PlayerController(可选,确保管理器有默认 PC)
在 的
PlayerController 中,将自身赋值给
BeginPlay 的
MyGameInstance,供管理器 fallback 使用:
CurrentPC
cpp
运行
#include "PlayerController.h"
#include "MyGameInstance.h"
void APlayerController::BeginPlay()
{
Super::BeginPlay();
// 将当前 PC 绑定到 GameInstance
if (UMyGameInstance* GI = Cast<UMyGameInstance>(GetGameInstance()))
{
GI->CurrentPC = this;
// (可选)初始化 UUMGManager 的默认 PC
if (UUMGManager* UIManager = GI->GetUMGManager())
{
UIManager->Initialize(this);
}
}
}
二、C++ 代码调用(核心场景)
在任何需要加载 UI 的地方(如 、
PlayerController、
GameMode),通过
Actor 获取
GameInstance 实例,再调用
UUMGManager。以下是 3 个典型场景示例:
LoadAndShowWidget
场景 1:在 PlayerController 中加载 “主菜单 UI”(纯 UI 交互,隐藏角色控制)
cpp
运行
#include "PlayerController.h"
#include "MyGameInstance.h"
#include "UMGManager.h"
// 示例:按 ESC 键加载主菜单
void APlayerController::SetupInputComponent()
{
Super::SetupInputComponent();
// 绑定 ESC 键输入事件
InputComponent->BindAction("OpenMainMenu", IE_Pressed, this, &APlayerController::OnOpenMainMenu);
}
void APlayerController::OnOpenMainMenu()
{
// 1. 获取 GameInstance 和 UUMGManager 实例
UMyGameInstance* GI = Cast<UMyGameInstance>(GetGameInstance());
if (!GI) return;
UUMGManager* UIManager = GI->GetUMGManager();
if (!UIManager)
{
UE_LOG(LogTemp, Error, TEXT("OnOpenMainMenu: UUMGManager 实例为空"));
return;
}
// 2. 定义 UI 路径(从 Content Browser 右键蓝图 → Copy Reference 获取)
FString MainMenuPath = "/Game/UI/WBP_MainMenu.WBP_MainMenu";
// 3. 调用 LoadAndShowWidget 加载 UI(自动设置输入模式为“仅 UI”+显示鼠标)
UUserWidget* MainMenuWidget = UIManager->LoadAndShowWidget(MainMenuPath, this); // 传入当前 PC
// 4. (可选)检查加载结果,处理异常
if (!MainMenuWidget)
{
UE_LOG(LogTemp, Error, TEXT("OnOpenMainMenu: 主菜单加载失败(路径:%s)"), *MainMenuPath);
}
else
{
UE_LOG(LogTemp, Log, TEXT("OnOpenMainMenu: 主菜单加载成功"));
}
}
场景 2:在 GameMode 中加载 “全局加载界面”(跨关卡持久化)
cpp
运行
#include "GameMode.h"
#include "MyGameInstance.h"
#include "UMGManager.h"
#include "GameFramework/PlayerController.h"
void AGameMode::BeginPlay()
{
Super::BeginPlay();
// 1. 获取 GameInstance 和 UUMGManager
UMyGameInstance* GI = Cast<UMyGameInstance>(GetGameInstance());
if (!GI || !GI->GetUMGManager()) return;
UUMGManager* UIManager = GI->GetUMGManager();
// 2. 获取默认 PlayerController(从 GameInstance 中获取,避免空指针)
APlayerController* DefaultPC = GI->CurrentPC.Get();
if (!DefaultPC) return;
// 3. 加载全局加载界面(无需传入 PC,管理器会用默认 PC)
FString LoadingUIPath = "/Game/UI/WBP_Loading.WBP_Loading";
UIManager->LoadAndShowWidget(LoadingUIPath); // 第二个参数省略,使用默认 PC
}
场景 3:隐藏 UI 并恢复输入模式(如关闭主菜单)
当关闭 UI 时,需调用之前新增的 函数,恢复 “游戏 + UI” 输入模式(让玩家重新控制角色):
HideWidget
cpp
运行
// 在 PlayerController 中添加“关闭主菜单”函数
void APlayerController::OnCloseMainMenu()
{
UMyGameInstance* GI = Cast<UMyGameInstance>(GetGameInstance());
if (!GI || !GI->GetUMGManager()) return;
UUMGManager* UIManager = GI->GetUMGManager();
FString MainMenuPath = "/Game/UI/WBP_MainMenu.WBP_MainMenu";
// 调用 HideWidget,传入 true 表示恢复输入模式
UIManager->HideWidget(MainMenuPath, true);
}
三、蓝图调用(给蓝图开发者使用)
如果需要在蓝图中调用 ,需先确保
UUMGManager 和
UMyGameInstance 的关键函数添加了
UUMGManager 宏(之前已配置)。以下是蓝图调用步骤:
UFUNCTION(BlueprintCallable)
1. 获取 UMyGameInstance 实例
在任何蓝图中(如 蓝图、
PlayerController 蓝图),通过 “获取游戏实例” 节点,转换为
Actor 类型:
MyGameInstance
蓝图节点路径:右键 “获取游戏实例” 节点的输出端 → 转换为 MyGameInstance
蓝图库 → 游戏实例 → 获取游戏实例
2. 获取 UUMGManager 实例
调用 的 “GetUMGManager” 函数(之前声明的蓝图可调用接口),获取管理器实例:
MyGameInstance
从 节点的输出端,拖拽出连线 → 搜索 “Get UMG Manager”
MyGameInstance
3. 调用 LoadAndShowWidget 加载 UI
从 节点的输出端,拖拽出连线 → 搜索 “Load And Show Widget”(需确保
UUMGManager 函数添加了
LoadAndShowWidget,若之前未加,需补充到
UFUNCTION(BlueprintCallable) 中):
UMGManager.h
cpp
运行
// 在 UMGManager.h 的 LoadAndShowWidget 声明中添加蓝图宏
UFUNCTION(BlueprintCallable, Category = "UI Management", meta = (DisplayName = "Load and Show UI"))
UUserWidget* LoadAndShowWidget(const FString& WidgetPath, APlayerController* InPC = nullptr);
输入参数:
:填写 UI 蓝图的完整路径(如
Widget Path);
/Game/UI/WBP_MainMenu.WBP_MainMenu(可选):传入当前
In PC(如蓝图的
PlayerController 节点,若为
Self 蓝图)。
PlayerController
4. 蓝图调用示例(关闭 UI 恢复输入)
同理,调用 的 “Hide Widget” 函数(需先给
UUMGManager 添加
HideWidget):
UFUNCTION(BlueprintCallable)
cpp
运行
// 在 UMGManager.h 的 HideWidget 声明中添加蓝图宏
UFUNCTION(BlueprintCallable, Category = "UI Management", meta = (DisplayName = "Hide UI and Restore Input"))
void HideWidget(const FString& WidgetPath, bool bRestoreGameInput = true);
蓝图节点:从 拖拽 → 搜索 “Hide UI and Restore Input”,传入 UI 路径和
UUMGManager。
bRestoreGameInput = true
四、调用注意事项
UI 路径必须正确:
路径从 右键蓝图 → Copy Reference 获取,确保包含完整的
Content Browser 前缀(如
/Game/),避免手动拼写错误。若路径错误,
/Game/UI/WBP_MainMenu.WBP_MainMenu 会返回
LoadAndShowWidget,并在 Output Log 中输出错误日志(搜索
nullptr 可查看)。
LogUMGManager
PlayerController 必须有效:
加载 UI 时,确保传入的 或管理器的
InPC 非空(否则 UI 无法挂载到视口,也无法设置输入模式)。若在
DefaultPC 中调用,需确保
BeginPlay 已初始化(如延迟 0.1 秒调用,避免关卡加载时 PC 未创建)。
PlayerController
输入模式冲突处理:
若同时加载多个 UI(如主菜单 + 弹窗),只有最后加载的 UI 会获取输入焦点。建议通过 “弹窗队列” 管理(在 中扩展),避免多个 UI 争抢输入。退出游戏时,需手动隐藏所有 UI 并恢复输入模式(可在
UUMGManager 的
MyGameInstance 函数中调用
Shutdown)。
UIManager->HideAllWidgets(true)
通过以上步骤,无论在 C++ 还是蓝图中,都能稳定调用 加载 UI 并设置输入模式,实现 “UI 交互” 与 “角色控制” 的无缝切换。
UUMGManager















暂无评论内容