总览
“打开菜单后角色还会开火”和“打开背包后鼠标不出来”通常不是按钮问题,而是输入模式问题。Common UI 用 FUIInputConfig 和 ECommonInputMode 描述当前 UI 需要什么。
三种输入模式
| 模式 | 含义 | 用途 |
|---|---|---|
Menu | 输入只给 UI,普通游戏输入被挡 | 主菜单、暂停、设置、确认框 |
Game | 输入只给游戏 | 纯 HUD,不需要 UI 输入 |
All | UI 和游戏都可能收到 | 地图预览、径向菜单、角色旋转预览 |
源码里 UCommonUIActionRouterBase::CanProcessNormalGameInput 会根据当前 ActiveInputMode 判断游戏输入是否继续处理。Menu 模式下通常会挡住 game input。
HUD 不一定要 Activatable
血条、小地图、任务追踪一般不接收输入,可以是普通 UUserWidget 或不声明输入配置的 Activatable。不要让 HUD 页面返回 Menu input config,否则进游戏后角色输入会被 HUD 自己挡住。
HUD 里如果有可交互元素,例如可点击任务追踪、Ping Wheel、小地图拖拽,可以局部打开一个 Activatable 页面并声明 All 或 Menu。
暂停菜单
暂停菜单一般:
- Push 到 Menu Stack。
bIsBackHandler=true- Desired InputConfig = Menu + NoCapture/DoNotLock。
- Desired Focus 返回“继续游戏”。
- Back 或 Continue 后 Deactivate,并恢复暂停前状态。
如果游戏真的 Pause,注意某些异步、动画和输入 Tick 也会受影响。UI 动画可以使用 UI 自己的 Tick/动画系统,gameplay 状态由 PlayerController 或 GameInstance 协调。
背包和角色预览
背包常见需求:UI 接管鼠标和手柄导航,但右摇杆或鼠标拖拽能旋转角色预览。可以用 All 输入模式,并在预览区域内处理旋转输入;也可以在打开预览子页时加页面专属 IMC。
关键是不要让 gameplay 的攻击/移动仍然生效。预览旋转应该是 UI/Preview Actor 的输入,不是角色 Pawn 的移动输入。
鼠标捕获
FUIInputConfig 除 InputMode 外还有 MouseCaptureMode、MouseLockMode、HideCursorDuringViewportCapture。PC 菜单通常不要捕获鼠标;游戏内准星 HUD 或拖拽预览可能需要捕获。遇到“鼠标一点击菜单就消失”或“鼠标不能离开窗口”,先看这里。
PlayerController 应该做什么
PlayerController 适合做:
- 创建 RootLayout。
- 打开/关闭顶层 UI。
- 暂停或恢复 gameplay。
- 保存当前输入/相机状态。
- 处理跨页面系统级事件。
具体页面不要直接操纵 Pawn 移动开关。页面只声明它的 Desired InputConfig,业务系统决定 gameplay 状态。
常见坑
- HUD 返回 Menu InputConfig,导致游戏一开始就收不到输入。
- 暂停菜单没有 Desired Focus,手柄无法点击继续。
- 背包用 All 但没有阻止 Pawn 攻击,玩家整理装备时开火。
- 打开菜单只调用
SetInputModeUIOnly,绕过 Common UI Router,ActionBar 和焦点恢复不同步。 - 鼠标捕获配置不对,菜单中鼠标被锁或隐藏。
源码依据
ECommonInputMode 只有 Menu、Game、All 三个值。FActivatableTreeRoot::ApplyLeafmostNodeConfig 会寻找 leaf-most node 的 Desired Input Config 并通过 Action Router 应用。UCommonUIActionRouterBase::SetActiveUIInputConfig 是当前 UI 输入配置入口;UCommonGameViewportClient 在 Axis 输入时如果 Router 判断不能处理普通游戏输入,会把输入标记为 handled,从而挡住游戏。
源码路径索引
CommonInput/Public/CommonInputModeTypes.hCommonUI/Public/Input/CommonUIActionRouterBase.hCommonUI/Private/Input/CommonUIActionRouterBase.cppCommonUI/Public/CommonGameViewportClient.h