Since version 3.0 there are new possibilities how to create events and how to connect events with controllers.
This is closer to the Unreal way and much easier to implement in a game. Be sure to check out the demo project.

First we need a Struct variable in which all actions are defined. To be able to access the variable everywhere I recommend to create a GameInstance Blueprint.




Select your new Blueprint in the project settings.




Create a new variable per player with the type "Simple Controller Mapping Profile".




In the Struct variable you can now define the actions for buttons and axes for your game.




Important! The StructID must be unique.
Always create a new ID for a new profile.




If you create two profiles for two players, remember to create a new ID for the second player when copying the first profile.




Now you can create a UI and let the user do a mapping. First we get the GameInstance and from it our variable.
Then we add the function "Start Mapping Button". This function waits 5 seconds until the user presses a button.
When a button is pressed "Successful" is triggered and the pressed button is associated with the action "Jump".
"Timer" is triggered every second. "Failed" is triggered when no button has been pressed or when "Allow Multiple Mapping" is disabled and the button is already mapped.




Now you can add the event "Controller Event Mapped Button" in your Pawn, Character Blueprint or in another Blueprint.
We get the variable again and add the action name "Jump".
Whenever the mapped button is pressed, "Action Pressed" will be triggered.




Works the same way for axes.
Here you can additionally select whether the axis event should only be triggered when moving the axis or in a certain frequency.




The mapping can be saved and loaded. The mapping is saved in the JSON format in the "Saved" directory.
In the Shipping Build on Windows it is the directory: C:\Users\UserName\AppData\Local\GameName

So it should be possible to upload the mapping in a (Steam)Cloud without any problems (not tested).




Since version 3.17, mappings can also be created manually without a user having to create them in a delivered build. The "mapButton" and "mapAxis" functions can be used to execute a mapping in blueprints.
The "createMappingFile" function can be used to create a new mapping file with the content of a previously created file.