Releasing InputEventJoypadButton events appearing to also register as InputEventKey is causing issues

Godot Version

Godot 4.5

Question

Hello! I’m currently working on a twin-stick shooter and I want to support both Keyboard&Mouse and Controllers properly. As such I wrote a relatively simple function to detect which type of input is being registered and to hide/unhide the mouse and grab/release UI focus accordingly. Here is that functon.

var is_using_controller : bool = false
var should_get_focus : Control

func _input(event: InputEvent) -> void:
## Check for controller stick movement with deadzone tolerance
	if event is InputEventJoypadMotion and is_using_controller == false:
		if abs(event.axis_value) > 0.1:
			is_using_controller = true
			Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
			should_get_focus.grab_focus()
## Check for controller button presses
	elif event is InputEventJoypadButton and is_using_controller == false:
		is_using_controller = true
		Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
		should_get_focus.grab_focus()
## check for mouse movement with some minor bump tolarence
	elif event is InputEventMouseMotion and is_using_controller == true:
		if abs(event.relative.x) > 5 or abs(event.relative.y) > 5:
			is_using_controller = false
			Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
			get_viewport().gui_release_focus()
##check for mouse or keyboard presses
	elif event is InputEventKey or InputEventMouseButton and is_using_controller == true:
		is_using_controller = false
		get_viewport().gui_release_focus()
		Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)

The issue I’m running into it that it seems that when I release a controller button it appears to be recognising that as an InputEventKey, since it runs the code under “elif event is InputEventKey” when a controller input is released.

If I remove the “is InputEventKey” from that if statement, then the system works fine (but obviously doesn’t switch to keyboard mode when a keyboard button is pressed)

Is this an engine bug or am I misunderstanding how the different input event types work? If it is a bug, any workaround suggestions?

This isn’t correct. event is InputEventKey or InputEventMouseButton is not the correct way to check if the event is an InputEventKey or if it is a InputEventMouseButton. That statement checks if the event is an InputEventKey or if InputEventMouseButton is true which it is because it exists. The correct way then is elif (event is InputEventKey or event is InputEventMouseButton) and is_using_controller == true:

The issue then is that when you press a joypad button is_using_controller is set to true and when you release the button the if statement will be interpreted as false or true and true which ends being true

Ah, that makes sense. It now works as expected. Thank you for the fix and thorough explanation.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.