Here’s the relevant code. The file linked above is the full file, which is part of an addon I created to handle a bunch of input things.
## For saving and loading the input map.
var _action_list: ActionList
## Loads any custom keybindings from disk and applies them to the InputMap.
func _ready() -> void:
_action_list = ActionList.load_or_create()
for action_name in _action_list.action_events:
for event_name in _action_list.action_events[action_name]:
_set_binding(action_name, _action_list.action_events[action_name][event_name])
restore_default_keybindings.connect(_on_restore_default_keybindings)
## Sets the passed event for the given action in the InputMap and saves it to
## disk for loading the next time the game is loaded.
func rebind_action(action: String, event: InputEvent) -> void:
_set_binding(action, event)
_save_binding(action, event)
## Sets the passed event for the given action in the InputMap for the game.
## This can result in either an additional option or overriding of an existing
## option.
##
## (E.G. if the action "move_up" was only mapped to the `W` key, passing in an
## InputEventKey event which presses the Up Arrow would overwrite the entry.
## However passing an InputEventJoypadMovementEvent of the left stick being
## moved up would add a new event.)
func _set_binding(action_to_remap: String, event: InputEvent) -> void:
var events = InputMap.action_get_events(action_to_remap)
for existing_event in events:
if existing_event.get_class() == event.get_class():
InputMap.action_erase_event(action_to_remap, existing_event)
break
InputMap.action_add_event(action_to_remap, event)
## Saves on disk the passed event for the passed action.
func _save_binding(action_name: String, event: InputEvent) -> void:
var action: Dictionary
if _action_list.action_events.has(action_name):
action = _action_list.action_events[action_name]
action[event_to_string(event)] = event
_action_list.action_events[action_name] = action
_action_list.save()
## Deletes the keybindings.tres file, resets the action_list variable
## to a default of empty, and then reloads all the settings the developer
## set in the inital game.
func _on_restore_default_keybindings() -> void:
_action_list.delete()
_action_list = ActionList.load_or_create()
InputMap.load_from_project_settings()