Detecting input devices in Godot
One thing I really like in games is the little touches and one of those little touches is when the control prompts match up with the input device I'm using.
YouTube: Detecting the input device to show custom controller inputs.
I wanted that for my game so I set about working out how to do that in Godot and, as with most things in Godot, it turned out to be easier than I expected.
You just need a node that implements _input()
and then to sniff out the event to see what it was.
I ended up with some code like this:
func _input(event: InputEvent) -> void:
var next_device: String = device
var next_device_index: int = device_index
# Did we just press a key on the keyboard?
if event is InputEventKey and event.is_pressed():
next_device = DEVICE_KEYBOARD
next_device_index = -1
# Did we just use a gamepad?
elif (event is InputEventJoypadButton and event.is_pressed()) \
or (event is InputEventJoypadMotion and event.axis_value > 0.1):
next_device = get_simplified_device_name(Input.get_joy_name(event.device))
next_device_index = event.device
if next_device != device or next_device_index != device_index:
device = next_device
device_index = next_device_index
emit_signal("device_changed", device, device_index)
So, if the last input was from a key being pressed we respond with "keyboard" as the active device.
If the last input was from a gamepad then we look at what Godot thinks the name of the game pad is.
I do a bit of tidying here on the actual device name to simplify which textures I need to load.
If the device has changed since last time then I emit a "device_changed" signal to notify my indicators.
Then, in the indicator, I can swap out which texture is showing as the input (I have some smarts in there to guess which actual key or button is mapped to the given action that I'm indicating).
func _on_input_device_changed(device: String, _device_index: int) -> void:
keyboard.visible = device == InputHelper.DEVICE_KEYBOARD
gamepad.visible = !keyboard.visible
match action:
Actions.Action:
key_label.text = InputHelper.get_key_label("ui_accept")
gamepad_sprite.texture = get_button_texture("ui_accept")
Actions.Inventory:
key_label.text = InputHelper.get_key_label("ui_inventory")
gamepad_sprite.texture = get_button_texture("ui_inventory")
I figured this input helper might be useful to other Godot devs so I've open sourced it as a Godot addon.
Give it a go and let me know what you think.