Ehanced Input System AddPlayerMappedKey not working

Hi everyone,

I’m currently trying to implement mappable keys with the Enhanced Input System but, when I try to change a mappable key by using the function AddPlayerMappedKey of the EnhancedInputLocalPlayerSubsystem I get the following warning.

 IEnhancedInputSubsystemInterface::AddPlayerMappedKeyInSlot Failed! Reasoning: (GameplayTags=((TagName="InputUserSettings.FailureReasons.NoMappingRowFound")))

Here’s what I did.
I’ve created an InputAction to move my player, and I’ve added it my InputMappingContext. Then in my Mapping Context, I’ve set all my keys to be mappable and I gave them a unique Name and a Display Name.
exemple of a key

I know that this part is correct because when I open my menu, I can get and display all my mappable keys by calling GetAllPlayerMappableActionKeyMappings on the EnhancedInputLocalPlayerSubsystem. Here’s my code on my widget to display the mappable keys.

UEnhancedInputLocalPlayerSubsystem* EnhancedInputSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer());
if (EnhancedInputSubsystem)
{
	// For each key, create a key widget and add it to the Keybinding vertical box
	TArray<FEnhancedActionKeyMapping> BindableKeys = EnhancedInputSubsystem->GetAllPlayerMappableActionKeyMappings();
	for (FEnhancedActionKeyMapping& Key : BindableKeys)
	{
		FText KeyName = Key.GetDisplayName();
		UKeyMappingWidget* NewKeyWidget = Cast<UKeyMappingWidget>(CreateWidget<UKeyMappingWidget>(this, KeybindingsWidget));
		if (NewKeyWidget)
		{
			KeybindingsVerticalBox->AddChild(NewKeyWidget);
			NewKeyWidget->SetInputName(KeyName);
			NewKeyWidget->SetInputSelector(Key);
		}
	}
}

display keys

I’m using a Widget to display those keys, and I’ve got an Input Selector in it so I can plug myself on the OnKeySelected event.

void UKeyMappingWidget::NativeConstruct()
{
	Super::NativeConstruct();

	InputSelector->OnKeySelected.AddUniqueDynamic(this, &UKeyMappingWidget::OnKeySelected);
}

When the event is called, I’m sending the new Key selected with the Mapping Name to the EnhancedInputLocalPlayerSubsystem with the function AddPlayerMappedKey but all I get is the warning that I’ve print on the beginning of this topic.

Her’s my code of the call.

UEnhancedInputLocalPlayerSubsystem* EnhancedInputSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer());
if (!EnhancedInputSubsystem)
{
	return;
}

EnhancedInputSubsystem->AddPlayerMappedKey(MappingName,NewKey);

I’m probaly missing something in the procress and I can’t find what it is.

I’ve tried to follow step by step the process of AddPlayerMappedKey and I saw that at some point, we end up in the UEnhancedInputUserSettings::MapPlayerKey.
Here we’ll be calling 2 functions that will try to see if in the TMap PlayerMappedKeys of the EnhancedPlayerMappableKeyProfile, our key exist. (those functions are UEnhancedPlayerMappableKeyProfile::FindKeyMapping and FindKeyMappingRowMutable).
The thing is that this TMap is always empty for me, it can’t be set manually and it has the UPROPERTY Transient.
I don’t really understand how it’s supposed to get its data.

Can you please help me with that ? I might have forgot something in the process but I can’t really see what it is.

Thanks in advance.

Hi,
Since last week, I had some time to dig up more into this, in case if someone has the same problem.

So the Enhanced Input Local Player Subsystem has a Enhanced Input User Settings. This User Settings has a TMap of UEnhancedPlayerMappableKeyProfile named SavedKeyProfiles.
It’s those KeyProfiles that contains the TMap PlayerMappedKeys that interets me.

I managed to get a KeyProfile by simply using UEnhancedInputUserSettings::GetCurrentKeyProfile, it’s actually the only one that’s contained on my EnhancedInputUserSettings.
This KeyProfile’s named EnhancedPlayerMappableKeyProfile and has a Tag called InputUserSettings.Profiles.Default. When I look up it seems to correspond to a data that’s set in the Project Settings, in the EnhancedInput section. So I’m assuming that it’s all setup properly by the engine himslef.
project settings

The thing is that its TMap PlayerMappedKeys that interests me here is empty. And when I look on the comment above it, I see : “Dirty mappings will be serialized from UEnhancedInputUserSettings::Serialize”.
This function takes an FArchive as an argument and I’ve got to admit, it doesn’t seems very intuitive to me. Do I really need to setup an FArchive to be able to detect and use the keys that I’ve made mappable in my Player Input Mapping Context ?

I’ve found myself in a dead end, because when I tried to do it simply in Blueprints it worked ! And I found videos on youtube such as this one that does basically the same thing that I’ve done on Blueprints and that I’m doing on C++, and no FArchive had to be used.
So I don’t really see what I’m doing wrong here and why my PlayerMappedKeys is empty.

If anyone has implemented mappable keys on C++ with the Enhanced Input System, I’d be really curious to see how you’ve managed that part when you need to retrieve this TMap. Any help would be really apreciated.
Thanks in avance.

Hi,

I managed to find what was the issue in my code.
In the SetupInputComponent of my controller, I forgot to register my Mapping Context on the Enhanced Input User Settings.

I was already doing that on the Enhanced Input Local Player Subsystem and I tought this was enough.
EnhancedSusbsytem->AddMappingContext(InputMapping, 0);

But I had to get the Input User Settings from the Subsytem and register again in order to finally have my input in the PlayerMappedKeys.
Here’s the code that I has to add at the end of my SetupInputComponent.

if (UEnhancedInputUserSettings* UserSettings = EnhancedSusbsytem->GetUserSettings())
{
	UserSettings->RegisterInputMappingContext(InputMapping);
}
2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.