输入与焦点
自动关联目录:输入与焦点
1. 定位
UI 打开时,输入该给游戏还是给界面——这个问题没处理好,表现为"点 UI 时角色也动了"或"UI 打开后游戏没反应"。
一句话定位:用 SetInputMode 明确声明输入归属,不要靠 UI 是否可见来隐式决定。
2. 输入模式
| 模式 | 含义 |
|---|---|
GameOnly | 只给游戏 |
UIOnly | 只给 UI(鼠标可见、可点) |
GameAndUI | 两者都收(最常用也最容易出问题) |
FInputModeGameAndUI Mode;
Mode.SetWidgetToFocus(MyWidget->TakeWidget());
Mode.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
PC->SetInputMode(Mode);
PC->bShowMouseCursor = true;| 配套 | 说明 |
|---|---|
bShowMouseCursor | 是否显示鼠标 |
SetWidgetToFocus | 指定焦点控件 |
SetLockMouseToViewportBehavior | 鼠标是否锁在视口 |
打开菜单 → UIOnly;关闭 → GameOnly,这是最不容易出错的写法。GameAndUI 要给游戏输入做额外过滤。
3. CommonUI
CommonUI 是 UE 的多平台 UI 插件,解决手柄/键鼠/触屏下的导航与输入统一:
| 能力 | 说明 |
|---|---|
| 统一的输入路由 | 不同输入设备走同一套动作 |
| 导航 | 手柄的焦点导航 |
| 输入激活层 | UI 与游戏输入的分层管理 |
| 平台适配 | 不同平台的按键图标与行为 |
做主机或多平台项目应该用 CommonUI,自己手写导航很快会失控。
4. 焦点
| 要点 | 说明 |
|---|---|
| 焦点决定键盘/手柄输入给谁 | SetFocus / TakeWidget |
| 打开 UI 时要显式设置焦点 | 否则键盘输入仍进游戏 |
| 焦点链 | 导航顺序 |
| 失去焦点的时机 | 关闭 UI 要把焦点还给游戏 |
5. 代价与权衡
| 设计 | 收益 | 代价 | 什么时候不该用 |
|---|---|---|---|
UIOnly | 语义最清晰 | 游戏完全收不到输入 | 需要边看 UI 边操作时不行 |
GameAndUI | 灵活 | 容易误触发 | 需要额外过滤 |
| CommonUI | 多平台统一 | 学习成本与插件依赖 | 单平台(仅键鼠)项目可不用 |
| 显式设置焦点 | 避免输入丢失 | 要写几行 | 从不做——这是必须的 |
6. 踩坑与排查
| 坑 | 现象 | 怎么验证 |
|---|---|---|
| 打开 UI 但输入仍进游戏 | 穿透 | 检查 SetInputMode |
| UI 打开后游戏完全不动 | 模式选错 | 需要 GameAndUI 或关闭时切回 |
| 键盘输入没进 UI | 没设焦点 | SetWidgetToFocus |
| 鼠标不显示 | bShowMouseCursor | 显式设置 |
| 关闭 UI 后输入失效 | 没切回 GameOnly | 关闭流程要恢复 |
| 手柄无法导航 | 没用 CommonUI 或没配导航 | 见上文 |
| 鼠标锁死在视口 | Lock 行为设置 | 调整 SetLockMouseToViewportBehavior |
7. 排查顺序
1. 输入穿透?→ SetInputMode 是否设置
2. 键盘没反应?→ 是否 SetWidgetToFocus
3. 关闭后失效?→ 是否恢复到 GameOnly
4. 手柄导航?→ CommonUI
5. 鼠标行为?→ bShowMouseCursor 与 Lock 设置参考
- 输入映射与触发 · 输入与网络 · UMG 深入
- Pawn 与 Controller 与 PlayerState(输入在 Controller 侧)
许可协议:CC BY
作者:Davids
本文链接:https://hustjjd.github.io/d8894782.html
更新于:2026年10月10日