UE5.8 Enhanced Input 专题系列

UE5.8 Enhanced Input 专题(六):玩家改键、保存和 Profile

喂饭级实现按键设置页:启用 User Settings、标记 Player Mappable、注册 IMC、MapPlayerKey、UnMapPlayerKey、Reset、SaveSettings、多键位和多 Profile。

总览

改键不要直接改 UInputMappingContext::MapKey 当存档。UE5.8 的推荐路径是 UEnhancedInputUserSettings。它会为每个 Local Player 保存 UEnhancedPlayerMappableKeyProfile,每个 Profile 里有多行 FPlayerKeyMapping,每行按 Mapping Name 管理多个 Slot。

UE5.8 Enhanced Input 专题(六):玩家改键、保存和 Profile 配图
UE5.8 推荐用 EnhancedInputUserSettings 做玩家改键和保存,旧 PlayerMappableInputConfig 已弃用。

第一步:开启 User Settings

Project Settings > Engine > Enhanced Input:

  1. 开启 Enable User Settings
  2. User Settings Class 用默认 UEnhancedInputUserSettings,或换成自己的子类。
  3. Default Player Mappable Key Profile Class 用默认 Profile,或换成自己的 Profile 子类。
  4. Input Settings Save Slot Name 默认是 EnhancedInputUserSettings,会写到 Saved/SaveGames。

源码里 UEnhancedInputUserSettings 继承 USaveGame,提供同步 SaveSettings 和异步 AsyncSaveSettings

第二步:让映射可改

在 Input Action 或具体 Action Key Mapping 上添加 Player Mappable Key Settings。关键字段:

字段 用途
Name 保存用唯一 MappingName,例如 Input.MoveForward
DisplayName UI 显示名,例如“向前移动”
DisplayCategory UI 分类,例如“移动”
Metadata 可放图标、提示、能力资产等
SupportedKeyProfileIds 只在某些 Profile 下启用

FEnhancedActionKeyMappingSettingBehavior:继承 Action 设置、覆盖 Mapping 设置、忽略设置。W 和 UpArrow 都属于“向前移动”时,可以让它们共享 MappingName 但处于不同 Slot。

第三步:注册 IMC

改键 UI 要知道项目里有哪些可改键。可以显式注册:

UEnhancedInputUserSettings* Settings = Subsystem->GetUserSettings();
Settings->RegisterInputMappingContext(DefaultMappingContext);

也可以在 AddMappingContext 时使用:

FModifyContextOptions Options;
Options.bNotifyUserSettings = true;
Subsystem->AddMappingContext(DefaultMappingContext, 0, Options);

注册 IMC 后,Settings 会遍历 Context 里所有 Player Mappable 映射,在当前 Profile 创建 FPlayerKeyMapping

第四步:执行改键

FMapPlayerKeyArgs Args;
Args.MappingName = TEXT("Input.Jump");
Args.Slot = EPlayerMappableKeySlot::First;
Args.NewKey = EKeys::SpaceBar;
Args.bCreateMatchingSlotIfNeeded = true;

FGameplayTagContainer FailureReason;
Settings->MapPlayerKey(Args, FailureReason);

if (FailureReason.IsEmpty())
{
    Settings->ApplySettings();
    Settings->SaveSettings();
}

Slot 用来支持一个动作多个键位。常见 UI 是第一键位和第二键位:First 是主键,Second 是副键。Unmap 时用同样的 MappingName 和 Slot:

Settings->UnMapPlayerKey(Args, FailureReason);
Settings->ApplySettings();
Settings->SaveSettings();

查询当前键位

FPlayerMappableKeyQueryOptions Query;
Query.MappingName = TEXT("Input.Jump");
Query.SlotToMatch = EPlayerMappableKeySlot::First;

TArray<FKey> Keys;
Settings->GetActiveKeyProfile()->QueryPlayerMappedKeys(Query, Keys);

如果要显示设置页,通常遍历 GetActiveKeyProfile()->GetPlayerMappingRows(),按 DisplayCategory 分组,把每个 Row 的 Slot 显示成按钮。

重置默认

重置单行动作:

Settings->GetActiveKeyProfile()->ResetMappingToDefault(TEXT("Input.Jump"));
Settings->ApplySettings();
Settings->SaveSettings();

重置整个 Profile:

FGameplayTagContainer FailureReason;
Settings->ResetKeyProfileIdToDefault(Settings->GetActiveKeyProfileId(), FailureReason);

注意 UE5.8 里 ProfileIdString 是推荐字段;旧 ProfileId 从 5.6 起 deprecated。

多 Profile

很多游戏要“默认”“左手”“手柄”“无障碍”几套方案。可以创建新 Profile:

FPlayerMappableKeyProfileCreationArgs Args;
Args.ProfileStringIdentifier = TEXT("Input.Profile.LeftHand");
Args.DisplayName = NSLOCTEXT("Input", "LeftHandProfile", "Left Hand");
Args.ProfileType = UEnhancedPlayerMappableKeyProfile::StaticClass();
Args.bSetAsCurrentProfile = true;

UEnhancedPlayerMappableKeyProfile* Profile = Settings->CreateNewKeyProfile(Args);

切换 Profile 用 SetActiveKeyProfile。源码测试验证:Profile A 改过的键不会污染新建 Profile B,非激活 Profile 也能查询。

常见坑

  • Player Mappable Settings 的 Name 为空或重复,保存后 UI 找不到正确行。
  • 只改 IMC,不调用 SaveSettings,重启后丢失。
  • 注册 IMC 只注册当前地图加载的 Context,设置页看不到 Game Feature 插件里的键位。
  • 第一键位和第二键位都用 First Slot,后者覆盖前者。
  • 改键后没调用 ApplySettings 或没让 Subsystem 重建映射。
  • 继续使用 deprecated 的 UPlayerMappableInputConfig 做新系统。

源码依据

EnhancedInputUserSettings.h 定义 FMapPlayerKeyArgsFPlayerKeyMappingFKeyMappingRowUEnhancedPlayerMappableKeyProfileUEnhancedInputUserSettingsMapPlayerKeyUnMapPlayerKeyResetAllPlayerKeysInRowResetKeyProfileIdToDefaultCreateNewKeyProfileRegisterInputMappingContext 都是官方 API。PlayerMappableInputConfig.h 在 UE5.8 标记 deprecated,并建议使用 UEnhancedInputUserSettings

源码路径索引

  • EnhancedInput/Public/UserSettings/EnhancedInputUserSettings.h
  • EnhancedInput/Public/PlayerMappableKeySettings.h
  • EnhancedInput/Public/EnhancedActionKeyMapping.h
  • EnhancedInput/Public/PlayerMappableInputConfig.h
  • EnhancedInput/Source/InputEditor/Private/Tests/InputPlayerMappableKeysTests.cpp