How to stop Yoke and Joystick interference in controls?

Godot Version

v4.4.1.stable.official [49a5bc7b6]

Question

My game uses mouse+keyboard and controller as input.

This usually works fine, but a player reported the they Yoke (Logitech Yoke & Throttle Quadrant) and Joystick (Logitech Extreme 3D Pro) were interfering while trying to play with mouse and keyboard (using Steam). Here is a video: Twitch

Is there a way to prevent this from happening? (without asking the player to unplug the devices).

This is how Input Map is configured:

I attempted to solve it by configuring Steam Input for the game, but that didn’t help.

Thanks!

If they have a controller plugged in then it’s going to send inputs. They should fix their controller, or unplug it; steam input can mess with controllers too and/or allow users to easily disable a type of input.


You could track the last-used button and only read from that type of input, I’ve used “last-button-type” for changing input prompts from “press ‘E’” to “press ‘Y’”, but using such a system to ignore the other input style may be more difficult especially if you are using helper functions like Input.get_vector.

If using Input.get_vector (and it may still be the easiest way) you would need to separate your actions into keyboard_left/right/forward/backward and joy_left/right/forward/backward, then you could switch between them.

var using_keyboard: bool = true
func _unhandled_input(event: InputEvent) -> void:
	if event is InputEventKey:
		using_keyboard = true
	elif event is InputEventJoypadButton:
		# only track joypad buttons as they are more intentional than
		# motion, such as stick drift
		using_keyboard = false


func _physics_process(delta: float) -> void:
	var input_vector: Vector2
	if using_keyboard:
		input_vector = Input.get_vector(
			"keyboard_left",
			"keyboard_right",
			"keyboard_forward",
			"keyboard_backward")
	else:
		input_vector = Input.get_vector(
			"joy_left",
			"joy_right",
			"joy_forward",
			"joy_backward")

This can make it harder for the rare dual-input players that use joysticks for movement and mouse for looking, but they may have a special way around it such as steam input remapping to keyboard.

Another maybe simplier option is to add a setting to disable controller input entirely, going through your input map and either deleting the input for each action, or setting it to an absurd controller port.

func _on_toggled_controller_allowed(allow_controllers: bool) -> void:
	var actions := InputMap.get_actions()
	for action in actions:
		var inputs := InputMap.action_get_events(action)
		for input in inputs:
			if input is InputEventJoypadButton or input is InputEventJoypadMotion:
				# -1 seems to be "all devices", 99 is unreasonable
				input.device = -1 if allow_controllers else 99
1 Like

Thanks! will try adding the option to disable controllers, should be enough to fix this specific issue.

Note that disabling controller input by changing the actions may not stop the current active actions (the camera will keep spinning for example).

My workaround for that is to ask the player to restart the game to apply the change.

1 Like