UE5.8 Enhanced Input 专题系列

UE5.8 Enhanced Input 专题(十):多人、调试和生产规范

总结本地多人、网络边界、输入注入、ShowDebug EnhancedInput/InputSettings、PlayerInputDebugger、自动化测试、命名规范、性能和上线检查清单。

总览

输入系统上线后最怕“只有玩家知道它坏了”。你需要能回答:当前 Local Player 装了哪些 Mapping Context?哪个 Action 正在 Triggered?玩家改键保存到哪个 Profile?这个键为什么被另一个 Context 吃掉?多人时谁拥有这次输入?

UE5.8 Enhanced Input 专题(十):多人、调试和生产规范 配图
生产可用的输入系统要能解释当前玩家有哪些 Context、哪些 Action 正在触发、改键保存在哪里。

网络边界

Enhanced Input 是本地输入系统。客户端按键只说明玩家意图,不能当服务器事实。多人游戏里常见流程是:客户端本地响应输入,发 Server RPC 或激活 Ability,服务器验证距离、冷却、状态、资源和目标合法性。

不要把“客户端说我按下攻击”当作伤害依据。输入只发起行为,行为是否成立由服务器 gameplay 系统判断。

本地多人

UEnhancedInputLocalPlayerSubsystem 是每个 Local Player 一份。分屏项目不能把所有 Context 和 User Settings 都挂到 Player 0。每个玩家的 Controller、LocalPlayer、Subsystem、UserSettings、Profile 都应该独立。

调试时用屏幕打印 LocalPlayer Index、Active Profile、Applied Context 列表。很多“P2 控制不了角色”的问题,实际是 Context 加到了 P1 的 Subsystem 上。

输入注入

Subsystem 和 PlayerInput 支持输入注入:

Subsystem->InjectInputForAction(MoveAction, FInputActionValue(FVector2D(0.0f, 1.0f)), {}, {});
Subsystem->StartContinuousInputInjectionForAction(MoveAction, FInputActionValue(FVector2D(0.0f, 1.0f)), {}, {});
Subsystem->StopContinuousInputInjectionForAction(MoveAction);

这适合自动化测试、Replay 工具、AI 接管玩家、教学引导。不要把它当作弊入口暴露给普通客户端。

调试命令

UE5.8 EnhancedInput 的 Config/Input.ini 注册了自动补全命令:

ShowDebug EnhancedInput
ShowDebug WorldSubsystemInput
ShowDebug InputSettings

ShowDebug EnhancedInput 看当前 Mapping Context、Action、Trigger、Modifier。ShowDebug InputSettings 看玩家可改键和 User Settings。WorldSubsystemInput 用于实验性 World Subsystem。

UE5.8 源码里还带 Experimental PlayerInputDebugger 插件,依赖 EnhancedInput,可以作为编辑器调试窗口辅助观察输入。

自动化测试思路

Enhanced Input 自己的测试给了很好的模板:InputBindingTest.cpp 验证按键触发、模拟轴值、多键同 Action、输入组件栈优先级和消费;InputPlayerMappableKeysTests.cpp 验证注册 IMC、MapPlayerKey、UnMap、Reset、Multiple Profiles。

项目里可以做三类回归:

  • 角色基础输入:Move/Look/Jump/Interact。
  • 改键流程:保存、读取、重置、冲突提示。
  • Context 切换:菜单、载具、死亡、过场、分屏。

生产命名规范

建议统一:

  • Input Action:IA_MoveIA_LookIA_Interact
  • Mapping Context:IMC_DefaultIMC_MenuIMC_Vehicle
  • MappingName:Input.Move.ForwardInput.Combat.Fire
  • GameplayTag Input Mode:Input.Mode.GameplayInput.Mode.Menu
  • UI Action:IA_UIConfirmIA_UICancelIA_UINavigate

命名要同时服务代码、设置页和玩家显示。IA_E 这种名字上线后很快会变成债。

性能和重建

Add/Remove Context 会请求重建 Control Mappings。不要每帧 Add/Remove。一次状态切换里如果要加多个 Context,避免每个都 bForceImmediately=true。Modifier 和 Trigger 也别滥用 bShouldAlwaysTick,源码注释明确说这会影响性能,只适合特定自定义 Trigger。

上线检查清单

  • 所有 gameplay 输入都有 IA 语义名,不用物理按键命名。
  • Context 分层清楚,UI 和 Gameplay 不互相漏输入。
  • 可改键 Action 都有唯一 Player Mappable MappingName。
  • 改键前做 Query 冲突检测。
  • User Settings 能保存、读取、重置、Profile 切换。
  • 手柄 Move/Look 有死区和单独灵敏度。
  • 暂停下只有 UI Action 触发。
  • 本地多人每个 Local Player 独立 Subsystem 和 Profile。
  • 服务器验证输入发起的 gameplay 行为。
  • 开发包里知道怎么使用 ShowDebug EnhancedInput 和 InputSettings。

常见坑

  • Context 生命周期不成对,加了不移除。
  • 改键界面只在单人测过,分屏 P2 改了 P1 的键。
  • 自动化测试只测默认键位,没有测玩家改键。
  • Debug 命令不知道,问题全靠猜。
  • 把输入层和能力/状态机/角色状态写死耦合,后续菜单、载具、过场越改越乱。

源码依据

EnhancedInput/Config/Input.ini 注册 ShowDebug 命令。IEnhancedInputSubsystemInterface 提供输入注入和连续注入 API。UEnhancedPlayerInput 保存 ActionInstanceData、AppliedInputContextData、EnhancedActionMappings 和 CurrentInputMode。PlayerInputDebugger.uplugin 位于 Experimental 插件并依赖 EnhancedInput。InputEditor 的自动化测试覆盖绑定、输入栈、可改键和多 Profile。

源码路径索引

  • EnhancedInput/Config/Input.ini
  • EnhancedInput/Public/EnhancedInputSubsystems.h
  • EnhancedInput/Public/EnhancedPlayerInput.h
  • EnhancedInput/Public/EnhancedInputLibrary.h
  • Experimental/PlayerInputDebugger/PlayerInputDebugger.uplugin
  • EnhancedInput/Source/InputEditor/Private/Tests/InputBindingTest.cpp
  • EnhancedInput/Source/InputEditor/Private/Tests/InputPlayerMappableKeysTests.cpp