Skip to content

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 Settings or Async Save Settings only when the product chooses to persist it.
  • Base Apply Settings does not map keys or write the SaveGame. It only broadcasts On Settings Applied unless 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:

  1. enable User Settings;
  2. leave the default User Settings Class or choose a project subclass;
  3. choose the input settings save-slot name; and
  4. 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 Context on the user settings explicitly; or
  • when adding/removing a context on the local-player subsystem, pass FModifyContextOptions with 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 Row for all mappings under one Mapping Name;
  • Find Current Mapping for Slot for one named row/slot;
  • Get Mapped Keys in Row on a profile; and
  • Get Mapping Names for Key for 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 Settings can return None when 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 FInputChord modifier flags in the New Key field.
  • 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