Skip to content

Instantly share code, notes, and snippets.

@lemilonkh
Created October 22, 2023 07:53
Show Gist options
  • Save lemilonkh/97cb8935ed210423748b993077bdc7a4 to your computer and use it in GitHub Desktop.
Save lemilonkh/97cb8935ed210423748b993077bdc7a4 to your computer and use it in GitHub Desktop.
Godot 4 Controls Manager
class_name ControlsData extends Resource
@export var controls: Dictionary = {}
extends Node
signal changed
const CONTROLS_SAVE_PATH := "user://controls.tres"
func _ready() -> void:
load_controls()
func save_controls() -> void:
var actions := InputMap.get_actions()
var data := ControlsData.new()
for action in actions:
if action.begins_with("editor_") or action.begins_with("ui_"):
continue
data.controls[action] = InputMap.action_get_events(action)
var error := ResourceSaver.save(data, CONTROLS_SAVE_PATH)
if error != OK:
printerr("Failed to save controls! Error: ", error_string(error))
func load_controls() -> void:
if not ResourceLoader.exists(CONTROLS_SAVE_PATH, &"ControlsData"):
printerr("No saved controls data in ", CONTROLS_SAVE_PATH)
return
var data: ControlsData = ResourceLoader.load(CONTROLS_SAVE_PATH, &"ControlsData")
if not is_instance_valid(data):
printerr("Failed to load controls!")
return
for action in data.controls.keys():
for event in data.controls[action]:
replace_action_mapping(action, event)
changed.emit()
func replace_action_mapping(action_name: StringName, event: InputEvent) -> void:
var use_controller := event is InputEventJoypadButton or event is InputEventJoypadMotion
clear_action_mapping(action_name, use_controller)
InputMap.action_add_event(action_name, event)
func clear_action_mapping(action_name: StringName, use_controller: bool) -> void:
for event in InputMap.action_get_events(action_name):
var is_controller := event is InputEventJoypadButton or event is InputEventJoypadMotion
if is_controller == use_controller:
InputMap.action_erase_event(action_name, event)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment