总览
UInputMappingContext 是 Enhanced Input 的“输入层”。默认行走一层,载具一层,瞄准一层,菜单一层,调试一层。Context 之间可以叠加,优先级越高越先处理;如果高优先级映射消费了输入,低优先级就收不到。
Context 怎么拆
| Context | 优先级建议 | 典型内容 |
|---|---|---|
IMC_Default |
0 | Move、Look、Jump、Interact |
IMC_Combat |
10 | Aim、Fire、Reload、Melee |
IMC_Vehicle |
20 | Throttle、Brake、Steer、ExitVehicle |
IMC_Menu |
100 | Confirm、Cancel、Navigate、Tab |
IMC_Debug |
1000 | 开发者飞行、刷新、日志 |
不要在一个巨型 IMC 里塞完整游戏。这样做短期省事,长期每次开菜单、上车、进炮台都要写分支判断。
Add 和 Remove
FModifyContextOptions Options;
Options.bIgnoreAllPressedKeysUntilRelease = true;
Options.bForceImmediately = false;
Options.bNotifyUserSettings = false;
Subsystem->AddMappingContext(CombatMappingContext, 10, Options);
Subsystem->RemoveMappingContext(CombatMappingContext, Options);
bIgnoreAllPressedKeysUntilRelease 默认 true,作用很实用:如果玩家按着 E 打开一个新 Context,新 Context 里也有 E,不会在同一帧立刻触发。bForceImmediately 会同步重建,源码注释不推荐在连续加多个 Context 时打开,因为性能更差。bNotifyUserSettings 用于让 User Settings 注册或注销这个 IMC,做改键 UI 时才需要特别关注。
输入模式过滤
UE5.8 的 Enhanced Input 有 Input Mode Filtering。UEnhancedInputDeveloperSettings 里有 bEnableInputModeFiltering、DefaultMappingContextInputModeQuery 和 DefaultInputMode。Subsystem 暴露:
Subsystem->SetInputMode(NewModeTags);
Subsystem->AddTagToInputMode(TAG_InputMode_Menu);
Subsystem->RemoveTagFromInputMode(TAG_InputMode_Menu);
如果 IMC 的 InputModeQuery 和当前 InputMode 不匹配,它的映射不会参与处理。它适合“大模式过滤”,例如 Gameplay、Menu、PhotoMode;不建议拿来替代所有 Add/Remove Context,因为你仍然需要清晰的上下文生命周期。
使用案例:进入载具
进入载具时保留 IMC_Default 还是移除,取决于设计。如果上车后完全不能移动角色,可以移除 Default 并添加 Vehicle。如果上车后仍要 Look 或打开地图,可以把 Look 放进低层公共 IMC,把 Move 放 Default,把 Vehicle 加高优先级覆盖 Move。
Subsystem->RemoveMappingContext(DefaultMappingContext);
Subsystem->AddMappingContext(VehicleMappingContext, 20);
退出载具反过来执行。不要直接在 Move 回调里写 if (bInVehicle),那会让输入层失去意义。
使用案例:打开菜单
菜单可以加 IMC_Menu,优先级 100,并把 SetInputMode 切到 Input.Mode.Menu 之类的 GameplayTag。关闭菜单时移除 IMC 并恢复 Gameplay Mode。这样 UI 的 Esc/Cancel 不会漏到 gameplay 的 Pause/Interact。
Registration Tracking
UInputMappingContext 有 RegistrationTrackingMode。默认 Untracked;如果设为 CountRegistrations,引擎会统计 Add/Remove 次数,并在反初始化时对未移除的 Context 记录警告。这对多人、本地分屏和 Game Feature 插件尤其有用,可以发现“进入玩法加了一次,退出忘了移除”的泄漏。
常见坑
- 把高优先级菜单 Context 加上后忘记 Remove,回游戏后攻击键失效。
- 用
MapKey/UnmapKey做玩法切换。源码注释说这些更适合配置和按键绑定界面,玩法切换应该用 Context。 - Add 多个 Context 都
bForceImmediately=true,产生不必要重建。 - 同一个按键在多个 Context 都可触发,但没有设计优先级和消费策略。
- InputModeQuery 配了,但项目默认 Input Mode 没包含对应 Tag。
源码依据
UInputMappingContext 注释列出四类用途:预设控制器映射、载具控制、武器/抓钩等上下文映射、覆盖映射。IEnhancedInputSubsystemInterface::AddMappingContext 注释说明高优先级映射会先应用,消费输入后阻止低优先级。FModifyContextOptions 定义了 pressed key ignore、同步重建和通知 User Settings。
源码路径索引
EnhancedInput/Public/InputMappingContext.hEnhancedInput/Public/EnhancedInputSubsystemInterface.hEnhancedInput/Public/EnhancedInputDeveloperSettings.hEnhancedInput/Public/EnhancedPlayerInput.h