generated from krampus/template-godot4
Turns out you can just save control bindings as regular project settings under `input/`. Who knew?
This commit is contained in:
parent
e0dad987d2
commit
37257dc3fd
|
@ -21,7 +21,6 @@ run/max_fps=60
|
||||||
|
|
||||||
ClubCatalog="*res://src/equipment/clubs/club_catalog.tscn"
|
ClubCatalog="*res://src/equipment/clubs/club_catalog.tscn"
|
||||||
GameSettings="*res://src/game/game_settings.gd"
|
GameSettings="*res://src/game/game_settings.gd"
|
||||||
BindingLoader="*res://src/game/binding_loader.gd"
|
|
||||||
|
|
||||||
[debug]
|
[debug]
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
|
@ -19,6 +19,10 @@ var listening: bool = false:
|
||||||
@onready var button: Button = %Button
|
@onready var button: Button = %Button
|
||||||
|
|
||||||
|
|
||||||
|
func _get_settings_key() -> String:
|
||||||
|
return "input/%s" % key
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
# gdlint:ignore = private-method-call
|
# gdlint:ignore = private-method-call
|
||||||
super._ready()
|
super._ready()
|
||||||
|
@ -99,6 +103,12 @@ func rebind(event: InputEvent) -> void:
|
||||||
listening = false
|
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:
|
static func create(_key: StringName) -> ControlBinding:
|
||||||
var instance: ControlBinding = SCENE.instantiate()
|
var instance: ControlBinding = SCENE.instantiate()
|
||||||
instance.key = _key
|
instance.key = _key
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://src/ui/menus/settings_menu/control_binding/control_binding.gd" id="1_7mwhu"]
|
[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"
|
theme_type_variation = &"CheckerContainerOdd"
|
||||||
script = ExtResource("1_7mwhu")
|
script = ExtResource("1_7mwhu")
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ extends MarginContainer
|
||||||
|
|
||||||
const SETTINGS_GROUP := "Settings"
|
const SETTINGS_GROUP := "Settings"
|
||||||
const VOLUME_GROUP := "VolumeSliders"
|
const VOLUME_GROUP := "VolumeSliders"
|
||||||
|
const BINDINGS_GROUP := "ControlBindings"
|
||||||
|
|
||||||
@onready var bus_mixer_list: HBoxContainer = %BusMixerList
|
@onready var bus_mixer_list: HBoxContainer = %BusMixerList
|
||||||
@onready var control_binding_list: VBoxContainer = %ControlBindingList
|
@onready var control_binding_list: VBoxContainer = %ControlBindingList
|
||||||
|
@ -25,6 +26,12 @@ func _get_volume_sliders() -> Array[VolumeSlider]:
|
||||||
return elements
|
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:
|
func populate_control_bindings() -> void:
|
||||||
for action: StringName in InputMap.get_actions():
|
for action: StringName in InputMap.get_actions():
|
||||||
if not action.begins_with("ui_"):
|
if not action.begins_with("ui_"):
|
||||||
|
@ -47,12 +54,13 @@ func apply() -> void:
|
||||||
setting.apply()
|
setting.apply()
|
||||||
for mixer: VolumeSlider in _get_volume_sliders():
|
for mixer: VolumeSlider in _get_volume_sliders():
|
||||||
mixer.apply()
|
mixer.apply()
|
||||||
|
for binding: ControlBinding in _get_control_bindings():
|
||||||
|
binding.apply()
|
||||||
|
|
||||||
|
|
||||||
## Write all applied settings to disk.
|
## Write all applied settings to disk.
|
||||||
func save_settings() -> void:
|
func save_settings() -> void:
|
||||||
Game.settings.write()
|
Game.settings.write()
|
||||||
BindingLoader.write()
|
|
||||||
|
|
||||||
|
|
||||||
## Apply settings and close menu.
|
## Apply settings and close menu.
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
class_name BindingMap extends Resource
|
|
||||||
## Serializable action input map. Used by `BindingLoader`.
|
|
||||||
|
|
||||||
@export var bindings: Dictionary
|
|
Loading…
Reference in New Issue