An edit after the fact- it seems that this process has been massively simplified in 5.3. I haven’t had the time to upgrade to 5.3 and get a comprehensive look, but it may now be as simple as it should’ve been.
So the solution to this involves quite a few steps, and doing anything wrong breaks everything, but I’ve finally figured it out.
One note → Absolutely Never use RemovePlayerMappedKey
It will break everything.
First, you have to get an array of all your contexts. As far as I know, there’s no way to use this method and save to the contexts. Though, this may be considered a positive since you don’t have to save defaults- these contexts will always have their default values, meaning don’t check them for current values (cause they won’t be).
Second, you have to apply all your mappings from those contexts, making sure to enable apply immediately. This should be done on begin play.
The GetAllPlayerMappableActionKeyMappings macro in this image is just made cause I use it so often, but what it does is gets all the mappings from every context, checking if they’re player mappable. This can be done with a built in function of the same name, but that only checks active contexts. It can be substituted for this:
I have my GetKeybind in a function library, but you can put it anywhere. This is how I’ve implemented it. This will work so long as you’ve done the previous steps prior to calling this.
This is the function I'm using to change keybinds. Pretty simple- just use the name you've assigned to the keybind and make sure to call save.
This part forward is for saving and loading
After pushing these changes in the first step, check whether there is a save for keybinds already. If yes, load.
The loading is straightforward, just make sure to use the player controller input subsystem:
And the loading is even simpler. I’m using the same macro as I used before, and I’m just adding the data to a map in the savegame. Saving is done whenever a keybind is changed.