Enhanced Input User Settings: map, unmap, reset, apply, and save¶
At a glance
Owner: one UEnhancedInputUserSettings instance for each Enhanced Input
local player ·
Mapping identity: Mapping Name + Slot + Profile ID + optional Hardware
Device ID ·
Mapped value: one FKey ·
Edit result: Map Player Key, Un Map Player Key, and reset operations
populate a Gameplay Tag Container with failure reasons; they do not return
a success Boolean ·
Runtime timing: a settings change causes the local subsystem to rebuild
active control mappings, normally at a frame boundary ·
Apply is not Save: base Apply Settings only broadcasts
On Settings Applied; persistence is a separate sync or async save ·
Official pages: Enhanced Input User Settings ·
Map Player Key Args ·
Player Mappable Key Settings
The one-minute version¶
- Turn on Enable User Settings in the Enhanced Input project settings. The feature is off unless configured, and a disabled subsystem has no user settings object to return.
- Start from the player who opened the screen: Local Player → Enhanced Input
Local Player Subsystem →
Get Enhanced Input User Settings. Never assume player index 0 in split-screen. - Mark eligible action mappings with Player Mappable Key Settings and give each logical row a stable, unique Mapping Name. Then register the containing Input Mapping Context with the user settings.
- Registration makes player-mappable rows and their defaults available to the profile. It does not, by itself, activate that context for gameplay.
- A mapping row is not identified by its Input Action alone. Map with the
complete
FMapPlayerKeyArgs: Mapping Name, Slot,New Key, optional Hardware Device ID, and Profile ID String. Map Player Key,Un Map Player Key, and reset operations return failure tags, not a success pin. Treat a non-empty Failure Reason container as a rejected operation and repaint from the profile.- Duplicate-key policy is yours. Query the profile for mapping names already using a key, then account for contexts that can coexist, device policy, and reserved menu keys before changing anything.
- Mapping changes and persistence are separate. A successful edit updates the
profile and drives a control-mapping rebuild; call
Save SettingsorAsync Save Settingsonly when the product chooses to persist it. - Base
Apply Settingsdoes not map keys or write the SaveGame. It only broadcastsOn Settings Appliedunless your subclass adds behavior. - User settings are local input configuration. They are not replicated to the server or copied to another local player's profile.
Enable and retrieve the correct instance¶
In the Project Settings Enhanced Input section:
- enable User Settings;
- leave the default User Settings Class or choose a project subclass;
- choose the input settings save-slot name; and
- optionally choose a project profile class for custom per-profile behavior.
UEnhancedInputDeveloperSettings::bEnableUserSettings controls whether an
instance is created on each Enhanced Input subsystem. The class setting is the
extension point for sensitivity, accessibility, custom apply behavior, save
completion reporting, or project metadata alongside key mappings.
Retrieve through the initiating local player:
pseudocode — Blueprint ownership flow
BindingsScreen.GetOwningLocalPlayer()
-> Get Enhanced Input Local Player Subsystem
-> Get Enhanced Input User Settings
-> Is Valid?
true: open this player's profile draft
false: disable rebinding and report configuration/initialization failure
The local-player subsystem exposes On Post User Settings Initialized after
its settings object has been created and loaded for the first time. If a screen
can open during early player startup, wait for that signal rather than polling
or manufacturing a second settings object.
Do not use Load Or Create Settings from an arbitrary world object merely to
avoid a None return. Fix the ownership/configuration path so the same instance
used by that player's UEnhancedPlayerInput also owns the screen's changes.
Make mappings discoverable before editing them¶
Player Mappable Key Settings provide row identity¶
An Input Action or an individual action-key mapping can provide
UPlayerMappableKeySettings. An IMC mapping chooses whether to:
- inherit the settings from its Input Action;
- override them for this mapping; or
- ignore them.
The settings object supplies:
| Field | Purpose |
|---|---|
Name |
Stable, unique Mapping Name used in the profile and save data |
Display Name |
Localized player-facing row label |
Display Category |
Localized grouping label for the settings screen |
Metadata |
Optional project object such as an icon or ability descriptor |
| Supported Profile IDs | Limit the row to selected profiles when the product needs that policy |
Persist and dispatch the Mapping Name, not the translated label and not an array index. One Input Action can legitimately appear in more than one mapping row, so the action asset alone is not sufficient identity.
Registering is not activating¶
Register Input Mapping Context scans that IMC and creates initial
FPlayerKeyMapping records for mappings marked player-mappable. Registration
also supplies the default keys that reset operations return to.
There are two normal registration routes:
- call
Register Input Mapping Contexton the user settings explicitly; or - when adding/removing a context on the local-player subsystem, pass
FModifyContextOptionswith Notify User Settings enabled.
The Notify option defaults to false. If it is omitted, adding an IMC for gameplay does not automatically make its rows available to the user settings.
Keep these two sets distinct:
| Set | Means |
|---|---|
| Registered IMCs | Their player-mappable rows/defaults are known to the settings/profile UI |
| Applied IMCs | Their mappings currently participate in this player's runtime input stack |
A settings screen may need rows from a currently inactive mode or an unloaded Game Feature. Explicit registration supports that catalogue without pretending every IMC is active at once.
Mapping Name, slot, profile, device, and key¶
FMapPlayerKeyArgs describes one edit:
| Argument | Meaning | Common trap |
|---|---|---|
Mapping Name |
Logical row to edit | Passing the Input Action object's name when the mappable settings use another name |
Slot |
One binding position in that row (First through Seventh, or Unspecified) |
Treating a UI array index as stable slot identity |
New Key |
The new FKey for Map |
Passing an FInputChord concept and silently losing its modifiers |
Hardware Device ID |
Optional device-specific mapping discriminator | Assuming “gamepad” alone identifies every supported hardware policy |
Profile ID String |
Profile to edit; empty means the currently equipped profile | Editing an inactive profile while repainting from the active one |
Create Matching Slot If Needed |
Create a missing slot/device mapping when allowed | Accidentally inventing a secondary binding instead of reporting bad identity |
Defer On Settings Changed Broadcast |
Delay the change notification until the next frame | Reading it as “do not change the profile yet” |
The older Gameplay Tag ProfileId field inside the struct is deprecated in
5.8; use ProfileIdString. That is separate from the current
EPlayerMappableKeySlot enum, which the current API still uses.
An FPlayerKeyMapping record can report its current key, default key, Mapping
Name, Slot, device identifier, localized display name/category, associated
Input Action, validity, customization, and dirty state. Build rows from those
records rather than duplicating defaults in a widget Blueprint.
Profiles and rows¶
UEnhancedPlayerMappableKeyProfile groups rows for one selectable key profile.
A row is keyed by Mapping Name and can contain several FPlayerKeyMapping
records—commonly a primary and secondary slot, and potentially device-specific
variants.
Useful queries include:
Find Mappings in Rowfor all mappings under one Mapping Name;Find Current Mapping for Slotfor one named row/slot;Get Mapped Keys in Rowon a profile; andGet Mapping Names for Keyfor duplicate/conflict discovery.
Check returned pointers/references for validity where the Blueprint node exposes that distinction. A missing row or slot is configuration/identity failure, not a reason to display the requested key optimistically.
Set Active Key Profile(ProfileIdString) returns a success Boolean. Switching
profiles changes which profile supplies player keys to runtime mapping rebuilds;
repaint the whole bindings screen from the newly active profile after success.
An empty ProfileIdString in map arguments means “the currently equipped
profile,” so explicit IDs are safer for a draft editor that can inspect several
profiles at once.
Map, unmap, and reset are different edits¶
| Operation | What changes | What it does not mean |
|---|---|---|
Map Player Key |
Sets New Key for the matching Mapping Name/Slot/device in the chosen profile |
Resolve product conflicts or save to disk |
Un Map Player Key |
Unmaps the single matching Mapping Name/Slot/device | Restore its IMC default |
Reset All Player Keys in Row |
Restores every slot in one Mapping Name row from registered IMC defaults | Reset only the selected slot |
Reset Key Profile Id to Default |
Restores all mappings in the named profile | Save or switch to that profile |
Map Player Key, Un Map Player Key, and the user-settings reset functions
have execution output plus a Failure Reason Gameplay Tag Container. They do
not return bool.
pseudocode — one accepted mapping edit
FailureReasons = empty
UserSettings.MapPlayerKey(Args, FailureReasons)
if FailureReasons is not empty:
show project text for the returned tags
repaint row from the profile selected by Args
else:
update draft/UI from the profile selected by Args
mark persistence pending
Clear the container before each call. Do not show raw internal tag names as the only player-facing error; map them to localized explanations and log the exact tags for diagnosis.
Map Player Key¶
Use Map after reserved-key and conflict policy accepts the candidate. Leave
Create Matching Slot If Needed off when a missing row/slot indicates broken
content. Turn it on only when the product deliberately lets players add a new
slot for that row/device.
New Key is one FKey. The Input Key Selector returns an FInputChord; if
modifier flags are enabled, the project must model them separately or reject
them. Truncating Ctrl+E to E is data loss.
Un Map Player Key¶
Unmap targets the record matching Mapping Name, Slot, and Hardware Device ID. Use it for a deliberate Clear binding action. If the game requires at least one binding for critical actions, enforce that invariant before unmapping.
Unmap is not Reset. After unmap, the slot is intentionally unbound; after reset, it returns to its registered default where one exists.
Reset row or profile¶
Reset All Player Keys in Row resets every mapping in the row. Mappings that
were added by the player rather than registered from an IMC reset to an invalid
key because no IMC default exists.
For a one-slot “Reset” button, read that FPlayerKeyMapping's Default Key and
submit a normal Map request for the same row/slot/device. For “Reset action,”
use the row operation. For “Reset all controls,” use the profile reset. Label
the scope accurately before confirmation.
Defaults come from registered mapping content. If an IMC default changes in a new game version, registration updates profile metadata/default information; the player's current customization remains a separate value until reset or project migration policy changes it.
Conflict policy is not supplied by Map Player Key¶
The profile being edited can list every Mapping Name using a proposed FKey
through Get Mapping Names for Key. That is a candidate set, not a final
conflict list.
Filter it through product rules:
- Can the two mapping contexts be active together?
- Are the mappings for the same device policy?
- Is sharing intentional, such as one key doing the same action in mutually exclusive modes?
- Is the key reserved for UI escape, accessibility, platform, or debug use?
- Would unmapping/replacing leave a required action unreachable?
Then present Replace, Swap, Keep Both, or Cancel as supported by the game. For Replace/Swap, validate the whole transaction first, perform every required map/unmap operation, collect all failure tags, and repaint every affected row. Do not change one widget before the model knows the complete transaction can hold.
Failure-reason tags from Map/Unmap report whether the requested operation could be performed. They are not a complete product-specific duplicate-key policy.
Runtime rebuild timing¶
User settings expose On Settings Changed; the Enhanced Input subsystem binds
to user-setting changes such as a new key mapping. Active control mappings are
then reapplied through the subsystem's rebuild path.
The normal rebuild contract is frame-boundary work:
Map / Unmap / Reset
-> profile changes
-> On Settings Changed
-> local subsystem requests control-mapping rebuild
-> active IMCs are reapplied at a frame boundary
-> On Control Mappings Rebuilt fires for that local player
Defer On Settings Changed Broadcast delays the settings-changed notification
until the next frame, so it can push the resulting rebuild later as well. It is
useful for batching several coherent edits; it is not a save or rollback
transaction.
Do not test the new gameplay binding on the same execution stack as the Map
call and declare failure. Observe On Control Mappings Rebuilt or test on a
later frame. A manual Request Rebuild Control Mappings also defaults to end
of frame; FModifyContextOptions::bForceImmediately exists for a genuine
same-frame requirement, but forcing rebuilds repeatedly is not a substitute for
batching settings changes.
When rebuilding while a key is held, consider the modify-context option that ignores pressed keys until release. Without a deliberate policy, the key used to confirm a binding can also actuate the newly mapped action.
Apply and Save are separate boundaries¶
This is the most important naming trap on the page.
Apply Settings¶
On the base UEnhancedInputUserSettings, Apply Settings only broadcasts
On Settings Applied. Epic describes it as a hook for custom settings and UI
updates. It does not perform Map Player Key, does not guarantee a control-map
rebuild beyond changes already notified, and does not write the SaveGame.
A project subclass may override Apply to commit sensitivity, accessibility, or
other custom input fields. Document that subclass contract; do not assume the
base node behaves like UGameUserSettings::ApplySettings.
Save Settings¶
Save Settings synchronously writes the settings to the configured/hardcoded
input SaveGame slot. It is simple, but synchronous I/O can hitch; use it at a
controlled boundary rather than on every captured key.
Async Save Settings returns immediately and later calls the protected virtual
OnAsyncSaveComplete(SlotName, UserIndex, bSuccess). The stock Blueprint node
has no completion or success output pin. If Blueprint UI must truthfully show
“saved” versus “save failed,” expose that result from a project
UEnhancedInputUserSettings subclass or integrate serialization into the
project's broader save system.
On Settings Applied is not async-save completion. Do not use it to display a
successful-save message.
For a draft-style options screen, use this order:
Open -> snapshot current profile mappings
Edit -> validate and Map/Unmap/Reset accepted draft changes
Apply -> call project Apply hook if the subclass owns custom fields
Persist -> sync/async Save according to product policy
Cancel -> restore the snapshot through validated mapping operations
Because mapping edits can affect runtime input after rebuild, a screen that promises “Cancel restores controls” must actually restore its snapshot; merely closing the widget is not rollback.
Split-screen and multiplayer¶
The settings object belongs to a UEnhancedPlayerInput and represents one User
or Local Player. GetSaveFilename(LocalPlayer) exists so persistence can be
derived for that owner. In local split-screen:
- start from the widget's owning Local Player;
- map through that player's local subsystem and settings object;
- keep capture, active profile, dirty state, and save feedback per player; and
- never use “Get Player Controller 0” as a rebinding shortcut.
UEnhancedInputUserSettings is a USaveGame-derived local configuration
object, not a replicated Actor or replicated component. Mapping changes affect
how that local player turns hardware input into Input Actions. They are not
replicated to the server, another client, or another local player.
That is the correct multiplayer boundary: the client evaluates its local key and sends the resulting gameplay intent through the project's ordinary server-authoritative RPC/ability/movement path. The server should authorize “Jump,” not need to know whether this player pressed Space or Gamepad Face Button Bottom.
When it fails (and what failure does)¶
Get Enhanced Input User Settingscan returnNonewhen user settings are disabled or not initialized for that local subsystem.- An unregistered IMC contributes no player-mappable rows/defaults to query.
- A missing Mapping Name, wrong Profile ID String, wrong Slot, or mismatched Hardware Device ID can make the requested record unavailable. Reusing one Mapping Name for unrelated mappings can instead merge them into one logical row and make the UI's target ambiguous.
- Map/Unmap/Reset can populate Failure Reason tags; there is no success Boolean on those nodes.
- A deferred rebuild means the profile can already show the new key before the runtime mapping has rebuilt.
- A duplicate can be technically accepted while violating the game's conflict policy if the coordinator never checks it.
- Synchronous Save has no success output; Async Save has no public Blueprint completion pin on the base class.
- A save can fail even though the live profile and runtime mapping already changed.
On any edit failure, retain/re-read the authoritative profile record and show a localized reason. On persistence failure, keep a pending-save state and offer a retry; do not claim the mapping edit itself was rolled back unless the project actually performs that rollback.
The deprecated path¶
UPlayerMappableInputConfig, Add Player Mappable Config, and the older
subsystem player-mapped-key functions were deprecated in favor of
UEnhancedInputUserSettings starting in UE 5.3. Current content should use
Player Mappable Key Settings on Input Actions/IMC mappings, registered IMCs,
profiles, and the FMapPlayerKeyArgs operations described here.
Do not misread the old release-note reference to FPlayerMappableKeySlot as a
reason to avoid the current EPlayerMappableKeySlot field. The 5.8
FMapPlayerKeyArgs API still uses the enum for slots; the similarly named older
type/functions belonged to the deprecated path.
What User Settings do not do¶
- They do not capture a key from UMG.
- They do not make every IMC mapping player-mappable automatically.
- They do not activate a registered Input Mapping Context.
- They do not infer the desired Mapping Name from a localized label.
- They do not preserve
FInputChordmodifier flags in theNew Keyfield. - They do not define the game's reserved-key or conflict-resolution policy.
- Base Apply does not save, and Save does not call Apply for you.
- They do not replicate local bindings or replace server authority.
Lookalikes — which one do I want?¶
| Type / operation | Use it when | Do not confuse it with |
|---|---|---|
| Input Key Selector | Capturing/displaying a user candidate in UMG | Applying or saving a profile mapping |
| Input Action | Naming gameplay intent and defining its value type/triggers | A persistent mapping-row identity or physical key |
| Input Mapping Context | Declaring action/key mappings for a runtime context | A per-player profile; the shared asset is not edited by Map Player Key |
| Player Mappable Key Settings | Giving a mapping stable name and UI metadata | The current per-player key value |
| Enhanced Player Mappable Key Profile | Reading/grouping rows, slots, defaults, and current keys | The user-settings owner or SaveGame operation |
| Map / Unmap / Reset | Changing current profile mappings | Apply or persistence |
| Enhanced Input User Settings Apply | Running a project-overridable custom-settings hook | UGameUserSettings::ApplySettings, which has a different contract |
| Save / Async Save Settings | Persisting the local settings object | Runtime control-map rebuild or conflict validation |
Going deeper¶
- Input Key Selector: selected chord, capture events, cancel, and conflict handoff — capture a candidate without pretending the widget owns mapping policy.
- Add Mapping Context — applied-context priority, lifecycle, and local-player ownership.
- Input Action Event and Enhanced Input Action Values — consume the local mapping as authoritative gameplay intent.
- Options/settings screen architecture — draft, applied, persisted, cancel, and save-failure boundaries.
- Enhanced Input User Settings, Map Player Key Args, Enhanced Player Mappable Key Profile, and Enhanced Input Local Player Subsystem — current public ownership, profile, mapping, and rebuild surfaces.
- Engine source (requires engine access; we do not reproduce it):
UEnhancedInputUserSettings::MapPlayerKey,UnMapPlayerKey,ResetAllPlayerKeysInRow,ApplySettings,SaveSettings, andAsyncSaveSettingsinEngine/Plugins/EnhancedInput/Source/EnhancedInput/Private/UserSettings/EnhancedInputUserSettings.cpp;IEnhancedInputSubsystemInterface::OnUserSettingsChangedandRequestRebuildControlMappingsinEngine/Plugins/EnhancedInput/Source/EnhancedInput/Private/EnhancedInputSubsystemInterface.cpp; andUEnhancedInputLocalPlayerSubsystem::GetUserSettingsinEngine/Plugins/EnhancedInput/Source/EnhancedInput/Private/EnhancedInputSubsystems.cpp.