UE5.8 Enhanced Input 专题系列

UE5.8 Enhanced Input 专题(七):按键冲突检测和改键 UI

围绕 QueryMapKeyInActiveContextSet、FMappingQueryIssue、ReservedByAction、HidesExistingMapping、类型升降级讲清改键前如何提示、阻止、覆盖和重建。

总览

一个真正能用的改键界面,不是“捕获玩家按下的键然后保存”。它还要回答四个问题:这个键是否被保留?会不会遮住现有映射?会不会被现有映射遮住?键的类型和 Action 值类型是否匹配?

UE5.8 Enhanced Input 专题(七):按键冲突检测和改键 UI 配图
改键 UI 不只是捕获一个 FKey,还要判断冲突、保留键、类型匹配和用户意图。

Query API

Subsystem 提供两个查询:

TArray<FMappingQueryIssue> Issues;
const EMappingQueryResult Result = Subsystem->QueryMapKeyInActiveContextSet(
    DefaultMappingContext,
    JumpAction,
    EKeys::SpaceBar,
    Issues,
    DefaultMappingIssues::StandardFatal);

QueryMapKeyInActiveContextSet 用当前玩家已激活的 Context 集合;QueryMapKeyInContextSet 可以传一个自定义的优先级 Context 列表,适合设置页预览某个方案。

Issue 含义

Issue 大白话 UI 建议
ReservedByAction 被另一个 Action 独占保留 直接拒绝
HidesExistingMapping 新映射会遮住已有映射 提示覆盖
HiddenByExistingMapping 新映射会被已有映射挡住 提示无效
CollisionWithMappingInSameContext 同 Context 内冲突 让玩家确认或拒绝
ForcesTypePromotion 低维键绑定高维 Action 警告
ForcesTypeDemotion 高维轴绑定低维 Action 通常拒绝

DefaultMappingIssues::StandardFatal 包括保留、冲突和类型不匹配。你可以按项目需求放宽,例如允许同一个键同时打开地图和关闭地图,但不要默认全部放行。

保留键

UInputActionbReserveAllMappings。当一个 Action 保留所有映射时,Query 会返回 ReservedByAction,表示别的 Action 不应该抢这个键。适合系统级输入:Esc、截图、调试开关、无障碍快捷键。

改键 UI 流程

玩家点击“更改键位”
  -> UI 进入等待输入状态
  -> 捕获第一个有效 FKey
  -> QueryMapKeyInActiveContextSet
  -> 无 fatal issue:MapPlayerKey + ApplySettings + SaveSettings
  -> 可覆盖 issue:弹窗确认,确认后先 UnMap/覆盖,再保存
  -> fatal issue:显示原因,继续等待或取消

UI 文案要说人话:“空格已经绑定到跳跃,是否改为翻滚并清除跳跃的空格键?”不要直接显示 HidesExistingMapping

类型匹配案例

把键盘 W 绑给 IA_Move Axis2D 可以接受,因为映射级 Modifier 会把 1D 拼成 2D;把 Mouse X 这种 1D 轴绑给 Boolean Action 就很怪;把 Gamepad Left Stick 2D 绑给 Axis1D Action 可能丢掉 Y 轴。Query 的类型升降级 issue 就是提醒你别让玩家做出不可理解的绑定。

UI 数据结构建议

设置页不要直接存一堆按钮文本。建议每一行保存:

  • MappingName
  • DisplayName
  • DisplayCategory
  • Slot
  • CurrentKey
  • DefaultKey
  • HardwareDeviceId
  • AssociatedInputAction

这些都能从 FPlayerKeyMapping 读到。UI 只负责展示和发起改键,不要自己维护另一套真相。

常见坑

  • 改键前不 Query,玩家能把移动、交互、开火全绑到 E。
  • Query 只看当前 IMC,设置页却允许改未激活的载具/菜单 Context。
  • 覆盖时只设置新键,没有清理被覆盖动作的旧键,导致两个动作共用。
  • 对保留键只弹警告但仍允许保存,后续调试很痛苦。
  • 捕获键位时把鼠标移动 delta 当成要绑定的键。

源码依据

InputMappingQuery.h 定义 EMappingQueryResultEMappingQueryIssueFMappingQueryIssueDefaultMappingIssues::StandardFatalIEnhancedInputSubsystemInterface 暴露 QueryMapKeyInActiveContextSetQueryMapKeyInContextSetQueryKeysMappedToActionGetAllPlayerMappableActionKeyMappings

源码路径索引

  • EnhancedInput/Public/InputMappingQuery.h
  • EnhancedInput/Public/EnhancedInputSubsystemInterface.h
  • EnhancedInput/Public/InputAction.h
  • EnhancedInput/Public/UserSettings/EnhancedInputUserSettings.h