Add a simplified version of input remapping

This commit is contained in:
Henrique Campos 2020-02-12 19:42:12 -03:00
parent 2372fd155f
commit a76d9471f4
6 changed files with 234 additions and 269 deletions

View File

@ -0,0 +1,35 @@
extends Button
export(String) var action = "ui_up"
func _ready():
assert(InputMap.has_action(action))
set_process_unhandled_key_input(false)
display_current_key()
func _toggled(button_pressed):
set_process_unhandled_key_input(button_pressed)
if button_pressed:
text = "... Key"
release_focus()
else:
display_current_key()
func _unhandled_key_input(event):
# Note that you can use the _input callback instead, especially if
# you want to work with gamepads.
remap_action_to(event)
pressed = false
func remap_action_to(event):
InputMap.action_erase_events(action)
InputMap.action_add_event(action, event)
text = "%s Key" % event.as_text()
func display_current_key():
var current_key = InputMap.get_action_list(action)[0].as_text()
text = "%s Key" % current_key

View File

@ -0,0 +1,12 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://ActionRemapButton.gd" type="Script" id=1]
[node name="ActionRemapButton" type="Button"]
margin_right = 90.0
margin_bottom = 30.0
toggle_mode = true
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}

View File

@ -0,0 +1,173 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://ActionRemapButton.tscn" type="PackedScene" id=1]
[sub_resource type="ButtonGroup" id=1]
[node name="InputRemapMenu" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
[node name="Instructions" type="Label" parent="."]
anchor_right = 1.0
margin_top = 24.0
margin_bottom = 55.0
text = "Click on a button to reassign its action key."
align = 1
autowrap = true
__meta__ = {
"_edit_use_anchors_": false
}
[node name="RemapButtonGroup" type="Button" parent="."]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -160.0
margin_top = -144.0
margin_right = 160.0
margin_bottom = 144.0
disabled = true
group = SubResource( 1 )
flat = true
__meta__ = {
"_edit_use_anchors_": false
}
[node name="ActionsList" type="VBoxContainer" parent="RemapButtonGroup"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -160.0
margin_top = -140.0
margin_right = 160.0
margin_bottom = 140.0
__meta__ = {
"_edit_use_anchors_": false
}
[node name="ActionRemapRow" type="HBoxContainer" parent="RemapButtonGroup/ActionsList"]
margin_right = 320.0
margin_bottom = 52.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="ActionName" type="Label" parent="RemapButtonGroup/ActionsList/ActionRemapRow"]
margin_right = 158.0
margin_bottom = 52.0
size_flags_horizontal = 3
size_flags_vertical = 3
text = "Move Left"
align = 1
valign = 1
[node name="RemapButton" parent="RemapButtonGroup/ActionsList/ActionRemapRow" instance=ExtResource( 1 )]
margin_left = 162.0
margin_right = 320.0
margin_bottom = 52.0
size_flags_horizontal = 3
size_flags_vertical = 3
group = SubResource( 1 )
action = "move_left"
[node name="ActionRemapRow2" type="HBoxContainer" parent="RemapButtonGroup/ActionsList"]
margin_top = 56.0
margin_right = 320.0
margin_bottom = 108.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="ActionName" type="Label" parent="RemapButtonGroup/ActionsList/ActionRemapRow2"]
margin_right = 158.0
margin_bottom = 52.0
size_flags_horizontal = 3
size_flags_vertical = 3
text = "Move Right"
align = 1
valign = 1
[node name="RemapButton" parent="RemapButtonGroup/ActionsList/ActionRemapRow2" instance=ExtResource( 1 )]
margin_left = 162.0
margin_right = 320.0
margin_bottom = 52.0
size_flags_horizontal = 3
size_flags_vertical = 3
group = SubResource( 1 )
action = "move_right"
[node name="ActionRemapRow3" type="HBoxContainer" parent="RemapButtonGroup/ActionsList"]
margin_top = 112.0
margin_right = 320.0
margin_bottom = 164.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="ActionName" type="Label" parent="RemapButtonGroup/ActionsList/ActionRemapRow3"]
margin_right = 158.0
margin_bottom = 52.0
size_flags_horizontal = 3
size_flags_vertical = 3
text = "Look Up"
align = 1
valign = 1
[node name="RemapButton" parent="RemapButtonGroup/ActionsList/ActionRemapRow3" instance=ExtResource( 1 )]
margin_left = 162.0
margin_right = 320.0
margin_bottom = 52.0
size_flags_horizontal = 3
size_flags_vertical = 3
group = SubResource( 1 )
action = "look_up"
[node name="ActionRemapRow4" type="HBoxContainer" parent="RemapButtonGroup/ActionsList"]
margin_top = 168.0
margin_right = 320.0
margin_bottom = 220.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="ActionName" type="Label" parent="RemapButtonGroup/ActionsList/ActionRemapRow4"]
margin_right = 158.0
margin_bottom = 52.0
size_flags_horizontal = 3
size_flags_vertical = 3
text = "Crouch"
align = 1
valign = 1
[node name="RemapButton" parent="RemapButtonGroup/ActionsList/ActionRemapRow4" instance=ExtResource( 1 )]
margin_left = 162.0
margin_right = 320.0
margin_bottom = 52.0
size_flags_horizontal = 3
size_flags_vertical = 3
group = SubResource( 1 )
action = "crouch"
[node name="ActionRemapRow5" type="HBoxContainer" parent="RemapButtonGroup/ActionsList"]
margin_top = 224.0
margin_right = 320.0
margin_bottom = 280.0
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="ActionName" type="Label" parent="RemapButtonGroup/ActionsList/ActionRemapRow5"]
margin_right = 158.0
margin_bottom = 56.0
size_flags_horizontal = 3
size_flags_vertical = 3
text = "Dash"
align = 1
valign = 1
[node name="RemapButton" parent="RemapButtonGroup/ActionsList/ActionRemapRow5" instance=ExtResource( 1 )]
margin_left = 162.0
margin_right = 320.0
margin_bottom = 56.0
size_flags_horizontal = 3
size_flags_vertical = 3
group = SubResource( 1 )
action = "dash"

View File

@ -1,102 +0,0 @@
extends Control
# Note for the reader:
#
# This demo conveniently uses the same names for actions and for the container nodes
# that hold each remapping button. This allow to get back to the button based simply
# on the name of the corresponding action, but it might not be so simple in your project.
#
# A better approach for large-scale input remapping might be to do the connections between
# buttons and wait_for_input through the code, passing as arguments both the name of the
# action and the node, e.g.:
# button.connect("pressed", self, "wait_for_input", [ button, action ])
const INPUT_ACTIONS = [ "move_up", "move_down", "move_left", "move_right", "jump" ]
const CONFIG_FILE = "user://input.cfg"
var action # To register the action the UI is currently handling
var button # Button node corresponding to the above action
onready var bindings = $Bindings
onready var contextual_help = $ContextualHelp
func _ready():
# Load config if existing, if not it will be generated with default values
load_config()
# Initialise each button with the default key binding from InputMap
for action in INPUT_ACTIONS:
# We assume that the key binding that we want is the first one (0), if there are several
var input_event = InputMap.get_action_list(action)[0]
# See note at the beginning of the script
var button = bindings.get_node(action).get_node("Button")
button.text = OS.get_scancode_string(input_event.scancode)
button.connect("pressed", self, "wait_for_input", [action])
# Do not start processing input until a button is pressed
set_process_input(false)
# Input management
func _input(event):
# Handle the first pressed key
if event is InputEventKey:
# Register the event as handled and stop polling
get_tree().set_input_as_handled()
set_process_input(false)
# Reinitialise the contextual help label
contextual_help.text = "Click a key binding to reassign it, or press the Cancel action."
if not event.is_action("ui_cancel"):
# Display the string corresponding to the pressed key
var scancode = OS.get_scancode_string(event.scancode)
button.text = scancode
# Start by removing previously key binding(s)
for old_event in InputMap.get_action_list(action):
InputMap.action_erase_event(action, old_event)
# Add the new key binding
InputMap.action_add_event(action, event)
save_to_config("input", action, scancode)
func wait_for_input(action_bind):
action = action_bind
# See note at the beginning of the script
button = bindings.get_node(action).get_node("Button")
contextual_help.text = "Press a key to assign to the '" + action + "' action."
set_process_input(true)
# Load/save input mapping to a config file
# Changes done while testing the demo will be persistent, saved to CONFIG_FILE
func load_config():
var config = ConfigFile.new()
var err = config.load(CONFIG_FILE)
if err: # Assuming that file is missing, generate default config
for action_name in INPUT_ACTIONS:
var action_list = InputMap.get_action_list(action_name)
# There could be multiple actions in the list, but we save the first one by default
var scancode = OS.get_scancode_string(action_list[0].scancode)
config.set_value("input", action_name, scancode)
config.save(CONFIG_FILE)
else: # ConfigFile was properly loaded, initialize InputMap
for action_name in config.get_section_keys("input"):
# Get the key scancode corresponding to the saved human-readable string
var scancode = OS.find_scancode_from_string(config.get_value("input", action_name))
# Create a new event object based on the saved scancode
var event = InputEventKey.new()
event.scancode = scancode
# Replace old action (key) events by the new one
for old_event in InputMap.get_action_list(action_name):
if old_event is InputEventKey:
InputMap.action_erase_event(action_name, old_event)
InputMap.action_add_event(action_name, event)
func save_to_config(section, key, value):
# Helper function to redefine a parameter in the settings file.
var config = ConfigFile.new()
var err = config.load(CONFIG_FILE)
if err:
print("Error code when loading config file: ", err)
else:
config.set_value(section, key, value)
config.save(CONFIG_FILE)

View File

@ -1,153 +0,0 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://controls.gd" type="Script" id=1]
[node name="Controls" type="Control"]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -320.0
margin_top = -240.0
margin_right = 320.0
margin_bottom = 240.0
size_flags_horizontal = 2
size_flags_vertical = 2
script = ExtResource( 1 )
__meta__ = {
"__editor_plugin_screen__": "2D",
"_edit_use_anchors_": false
}
[node name="ContextualHelp" type="Label" parent="."]
margin_left = 130.0
margin_top = 100.0
margin_right = 533.0
margin_bottom = 139.0
size_flags_horizontal = 2
size_flags_vertical = 0
text = "Click on a key binding to reassign it, or press the Cancel action."
__meta__ = {
"_edit_use_anchors_": false
}
[node name="Bindings" type="VBoxContainer" parent="."]
margin_left = 150.0
margin_top = 150.0
margin_right = 350.0
margin_bottom = 450.0
size_flags_horizontal = 2
size_flags_vertical = 2
[node name="move_up" type="Control" parent="Bindings"]
size_flags_horizontal = 2
size_flags_vertical = 2
[node name="Label" type="Label" parent="Bindings/move_up"]
margin_left = 5.0
margin_top = 8.0
margin_right = 45.0
margin_bottom = 21.0
size_flags_horizontal = 2
size_flags_vertical = 0
text = "Up"
[node name="Button" type="Button" parent="Bindings/move_up"]
margin_left = 84.0
margin_top = -1.0
margin_right = 144.0
margin_bottom = 29.0
size_flags_horizontal = 2
size_flags_vertical = 2
[node name="move_down" type="Control" parent="Bindings"]
margin_top = 60.0
margin_bottom = 60.0
size_flags_horizontal = 2
size_flags_vertical = 2
[node name="Label" type="Label" parent="Bindings/move_down"]
margin_left = 5.0
margin_top = 8.0
margin_right = 45.0
margin_bottom = 21.0
size_flags_horizontal = 2
size_flags_vertical = 0
text = "Down"
[node name="Button" type="Button" parent="Bindings/move_down"]
margin_left = 84.0
margin_top = -1.0
margin_right = 144.0
margin_bottom = 29.0
size_flags_horizontal = 2
size_flags_vertical = 2
[node name="move_left" type="Control" parent="Bindings"]
margin_top = 120.0
margin_bottom = 120.0
size_flags_horizontal = 2
size_flags_vertical = 2
[node name="Label" type="Label" parent="Bindings/move_left"]
margin_left = 5.0
margin_top = 8.0
margin_right = 45.0
margin_bottom = 21.0
size_flags_horizontal = 2
size_flags_vertical = 0
text = "Left"
[node name="Button" type="Button" parent="Bindings/move_left"]
margin_left = 84.0
margin_top = -1.0
margin_right = 144.0
margin_bottom = 29.0
size_flags_horizontal = 2
size_flags_vertical = 2
[node name="move_right" type="Control" parent="Bindings"]
margin_top = 180.0
margin_bottom = 180.0
size_flags_horizontal = 2
size_flags_vertical = 2
[node name="Label" type="Label" parent="Bindings/move_right"]
margin_left = 5.0
margin_top = 8.0
margin_right = 45.0
margin_bottom = 21.0
size_flags_horizontal = 2
size_flags_vertical = 0
text = "Right"
[node name="Button" type="Button" parent="Bindings/move_right"]
margin_left = 84.0
margin_top = -1.0
margin_right = 144.0
margin_bottom = 29.0
size_flags_horizontal = 2
size_flags_vertical = 2
[node name="jump" type="Control" parent="Bindings"]
margin_top = 240.0
margin_bottom = 240.0
size_flags_horizontal = 2
size_flags_vertical = 2
[node name="Label" type="Label" parent="Bindings/jump"]
margin_left = 5.0
margin_top = 8.0
margin_right = 45.0
margin_bottom = 21.0
size_flags_horizontal = 2
size_flags_vertical = 0
text = "Jump"
[node name="Button" type="Button" parent="Bindings/jump"]
margin_left = 84.0
margin_top = -1.0
margin_right = 144.0
margin_bottom = 29.0
size_flags_horizontal = 2
size_flags_vertical = 2

View File

@ -16,7 +16,7 @@ _global_script_class_icons={
[application]
config/name="Input Mapping GUI"
run/main_scene="res://controls.tscn"
run/main_scene="res://InputRemapMenu.tscn"
config/icon="res://icon.png"
[display]
@ -32,14 +32,9 @@ singletons=[ ]
[input]
jump={
move_right={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"unicode":0,"echo":false,"script":null)
]
}
move_down={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null)
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null)
]
}
move_left={
@ -47,13 +42,18 @@ move_left={
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"unicode":0,"echo":false,"script":null)
]
}
move_right={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null)
]
}
move_up={
look_up={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null)
]
}
crouch={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null)
]
}
dash={
"deadzone": 0.5,
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777237,"unicode":0,"echo":false,"script":null)
]
}