UE5.8 Common UI 喂饭级专题

UE5.8 Common UI 喂饭级入门到实战专题

基于 UE5.8 CommonUI/CommonInput 源码,从插件启用、ViewportClient、Activatable Widget、Layer/Stack、输入路由、设备图标、按钮、Tab、Enhanced Input、HUD 与调试生产规范讲到真实项目怎么落地。

总览

Common UI 不是“UMG 里多几个按钮”。UE5.8 源码里的 CommonUI 插件默认不启用,包含 CommonUICommonInputCommonUIEditor 三个模块,插件可携带内容,并依赖 Enhanced Input。它真正解决的是游戏 UI 的四个老问题:页面进出场没有生命周期、手柄返回键到处乱绑、键鼠/手柄/触摸提示不统一、打开菜单后 gameplay 输入是否应该被挡住说不清。

一句话心智模型:Common UI 用 UCommonActivatableWidget 表示一个可激活页面,用 Stack/Queue 管页面层级,用 UCommonUIActionRouterBase 把输入先送到当前激活树,用 UCommonInputSubsystem 判断当前设备,再让 UCommonActionWidgetUCommonBoundActionBar 显示正确按键提示。

UE5.8 Common UI 喂饭级入门到实战专题 配图
Common UI 的核心不是“多几个按钮控件”,而是把页面生命周期、输入路由、焦点、设备提示和 UI 层级变成一套稳定协议。

专题分篇目录

篇章你会学到什么读完能做什么
先跑通第一个菜单启用插件、配置 ViewportClient、创建 RootLayout、Push 主菜单
Activatable Widget 生命周期分清 Construct、Activate、Deactivate、Destruct、返回键和焦点
Stack、Queue 和 UI Layer搭主菜单、弹窗、Toast、Loading、HUD 的层级
输入路由与 ActionBar注册 UI Action、显示按钮提示、处理 Back/Confirm/Hold
设备识别与按键图标配 CommonInputSettings、ControllerData、键鼠/手柄/触摸图标
按钮、Tab、List 和样式做可复用按钮、选项卡、列表项、锁定态、选中态和声音
和 Enhanced Input 怎么接用 InputAction、IMC Metadata、InputMapping 和 UI 输入上下文
Modal、异步加载与弹窗做设置页、确认框、异步图片/Widget、加载遮罩和队列弹窗
HUD、暂停菜单和 Gameplay 共存处理 UIOnly/GameOnly/All、鼠标捕获、游戏预览和角色输入
调试、性能和生产规范用 DumpActivatableTree、showdebug ActionRouter、命名、多人和上线清单

Common UI 解决的不是一个点

普通 UMG 项目最容易变成“每个 Widget 自己 AddToViewport、自己 Bind Esc、自己 SetInputMode”。做到第三个菜单后,返回键顺序、焦点恢复、手柄按钮提示、弹窗遮挡、暂停菜单和游戏输入就会互相干扰。Common UI 的做法是把 UI 看成一棵“激活树”:只有当前可接收输入的 leaf-most activatable widget 最该拿输入配置和焦点。

这也是为什么源码里 UCommonUIActionRouterBaseULocalPlayerSubsystem:UI 输入不是全局的,它属于本地玩家。分屏、本地双人、远程多人都不能靠一个全局单例处理。

先记住五个核心类型

类型负责什么初学者怎么理解
UCommonActivatableWidget页面生命周期、返回键、焦点、输入配置一个“可打开/可关闭”的页面
UCommonActivatableWidgetStack后进先出的页面栈主菜单推设置页,Back 回主菜单
UCommonActivatableWidgetQueue一个一个显示的队列Toast、奖励弹窗、确认结果
UCommonUIActionRouterBase把输入送给激活树UI 输入总调度器
UCommonInputSubsystem判断当前输入设备和图标数据键鼠/手柄/触摸提示管理器

推荐项目骨架

项目里建议先建四个基类:WBP_RootLayoutWBP_ActivatableScreenBaseWBP_CommonButtonBaseWBP_BoundActionButton。RootLayout 里放四个层:HUD、Menu、Modal、Toast。所有页面不要直接 AddToViewport,而是通过 RootLayout 的层 Push 或 Enqueue。

生产项目里 UI 入口通常放在 PlayerController 或 LocalPlayer 相关系统:玩家进入游戏后创建 RootLayout,加到 Viewport;打开背包、设置、暂停菜单时只调用 RootLayout 的 Push。这样每个页面只关心自己的内容和返回行为。

最小配置清单

[/Script/Engine.Engine]
GameViewportClientClassName=/Script/CommonUI.CommonGameViewportClient

[/Script/CommonInput.CommonInputSettings]
bEnableEnhancedInputSupport=True
bEnableDefaultInputConfig=True

CommonGameViewportClient 很关键。源码里它会把 InputKey/InputAxis/InputTouch 先 reroute 给 Common UI 的 Action Router;如果你没配置它,源码会在非 Shipping 下提示 CommonUI 输入路由不能正常工作。

常见坑

  • 把 Common UI 当成普通 UMG 控件库,只换按钮不换页面生命周期。
  • 忘记配置 CommonGameViewportClient,导致 Back、ActionBar 和输入阻断不稳定。
  • 所有页面都直接 AddToViewport,绕开 Stack/Queue 后返回路径无法维护。
  • 页面没有实现 Desired Focus,手柄打开后看似“没输入”。
  • UI Action、Gameplay Action 和改键系统各维护一套键位,最后提示图标和真实输入不一致。

源码依据

CommonUI.uplugin 在 UE5.8 里 EnabledByDefault=false,模块包含 CommonUICommonInputCommonUIEditor,并依赖 EnhancedInput。CommonGameViewportClient 注释明确写着它用于把输入先路由到 UI。UCommonUIActionRouterBase 是 LocalPlayerSubsystem,负责从 ViewportClient 收集输入并转发给 activatable tree。UCommonInputSubsystem 也是 LocalPlayerSubsystem,负责当前设备、手柄类型、图标显示和输入法切换。

源码路径索引

  • Engine/Plugins/Runtime/CommonUI/CommonUI.uplugin
  • CommonUI/Source/CommonUI/Public/CommonActivatableWidget.h
  • CommonUI/Source/CommonUI/Public/Widgets/CommonActivatableWidgetContainer.h
  • CommonUI/Source/CommonUI/Public/Input/CommonUIActionRouterBase.h
  • CommonUI/Source/CommonUI/Public/CommonGameViewportClient.h
  • CommonInput/Public/CommonInputSubsystem.h
  • CommonInput/Public/CommonInputSettings.h
  • CommonUI/Public/CommonButtonBase.h
  • CommonUI/Public/CommonActionWidget.h