Turns out you can just save control bindings as regular project settings under `input/`. Who knew?

This commit is contained in:
Rob Kelly 2024-12-10 12:36:49 -07:00
parent e0dad987d2
commit 37257dc3fd
6 changed files with 20 additions and 42 deletions

View File

@ -21,7 +21,6 @@ run/max_fps=60
ClubCatalog="*res://src/equipment/clubs/club_catalog.tscn"
GameSettings="*res://src/game/game_settings.gd"
BindingLoader="*res://src/game/binding_loader.gd"
[debug]

View File

@ -1,35 +0,0 @@
class_name BindingLoaderType extends Node
## Handles persisting action input bindings.
const BINDINGS_FILE := "user://bindings.tres"
func _ready() -> void:
# Map may not be defined if no keybinds have been written
if FileAccess.file_exists(BINDINGS_FILE):
print_debug("Reading keybinds from ", BINDINGS_FILE)
var map: BindingMap = load(BINDINGS_FILE) as BindingMap
# Overwrite InputMap with loaded bindings
for action: StringName in map.bindings.keys():
# Clear existing bindings
InputMap.action_erase_events(action)
# Apply loaded binding
var event: InputEvent = map.bindings[action]
if event:
InputMap.action_add_event(action, event)
func write() -> void:
# Build map from input actions
var map: BindingMap = BindingMap.new()
for action: StringName in InputMap.get_actions():
var events := InputMap.action_get_events(action)
if events:
map.bindings[action] = events[0]
else:
map.bindings[action] = null
# Write to disk
print_debug("Writing keybinds to ", BINDINGS_FILE)
ResourceSaver.save(map, BINDINGS_FILE)

View File

@ -19,6 +19,10 @@ var listening: bool = false:
@onready var button: Button = %Button
func _get_settings_key() -> String:
return "input/%s" % key
func _ready() -> void:
# gdlint:ignore = private-method-call
super._ready()
@ -99,6 +103,12 @@ func rebind(event: InputEvent) -> void:
listening = false
func apply() -> void:
var setting: Dictionary = ProjectSettings.get_setting(_get_settings_key())
setting["events"] = InputMap.action_get_events(key)
ProjectSettings.set_setting(_get_settings_key(), setting)
static func create(_key: StringName) -> ControlBinding:
var instance: ControlBinding = SCENE.instantiate()
instance.key = _key

View File

@ -2,7 +2,7 @@
[ext_resource type="Script" path="res://src/ui/menus/settings_menu/control_binding/control_binding.gd" id="1_7mwhu"]
[node name="ControlBinding" type="PanelContainer"]
[node name="ControlBinding" type="PanelContainer" groups=["ControlBindings"]]
theme_type_variation = &"CheckerContainerOdd"
script = ExtResource("1_7mwhu")

View File

@ -3,6 +3,7 @@ extends MarginContainer
const SETTINGS_GROUP := "Settings"
const VOLUME_GROUP := "VolumeSliders"
const BINDINGS_GROUP := "ControlBindings"
@onready var bus_mixer_list: HBoxContainer = %BusMixerList
@onready var control_binding_list: VBoxContainer = %ControlBindingList
@ -25,6 +26,12 @@ func _get_volume_sliders() -> Array[VolumeSlider]:
return elements
func _get_control_bindings() -> Array[ControlBinding]:
var elements: Array[ControlBinding] = []
elements.assign(get_tree().get_nodes_in_group(BINDINGS_GROUP))
return elements
func populate_control_bindings() -> void:
for action: StringName in InputMap.get_actions():
if not action.begins_with("ui_"):
@ -47,12 +54,13 @@ func apply() -> void:
setting.apply()
for mixer: VolumeSlider in _get_volume_sliders():
mixer.apply()
for binding: ControlBinding in _get_control_bindings():
binding.apply()
## Write all applied settings to disk.
func save_settings() -> void:
Game.settings.write()
BindingLoader.write()
## Apply settings and close menu.

View File

@ -1,4 +0,0 @@
class_name BindingMap extends Resource
## Serializable action input map. Used by `BindingLoader`.
@export var bindings: Dictionary