Add a simplified version of input remapping
This commit is contained in:
parent
2372fd155f
commit
a76d9471f4
|
@ -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
|
|
@ -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
|
||||
}
|
|
@ -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"
|
|
@ -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)
|
|
@ -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
|
|
@ -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)
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue