class_name PhysicalEventHandler extends Node signal on_trigger_pressed(axis_id : JoyAxis, pressed : bool, controller_id : int) signal on_button_pressed(button_id : JoyButton, pressed : bool, controller_id : int) @export var dead_zone : float = 0.1 @export var device_filter : Array[int] = [ 1 ] : set(value) : device_filter = value devices_state.clear() for i in value: if not devices_state.has(i): var state : GameControllerState = GameControllerState.new(i, dead_zone, on_trigger_pressed, on_button_pressed) devices_state[i] = state class GameControllerState: var left_stick : Vector2 = Vector2.ZERO var right_stick : Vector2 = Vector2.ZERO var trigger_left_active : bool = false var trigger_left : float = 0. var trigger_right_active : bool = false var trigger_right : float = 0. var pad_id : int var dead_zone : float var axis_signal : Signal var button_signal : Signal func _init(id : int, d : float, a_s : Signal, b_s : Signal): pad_id = id dead_zone = d axis_signal = a_s button_signal = b_s func handle_motion(jev : InputEventJoypadMotion) -> void: var value : float = 0. if abs(jev.axis_value) < dead_zone else jev.axis_value var not_pressed : bool = is_zero_approx(value) match jev.axis: JOY_AXIS_LEFT_X: left_stick.x = value JOY_AXIS_LEFT_Y: left_stick.y = value JOY_AXIS_RIGHT_X: right_stick.x = value JOY_AXIS_RIGHT_Y: right_stick.y = value JOY_AXIS_TRIGGER_LEFT: if not_pressed == trigger_left_active: trigger_left_active = !not_pressed axis_signal.emit(jev.axis, trigger_left_active, jev.device) trigger_left = value JOY_AXIS_TRIGGER_RIGHT: if not_pressed == trigger_right_active: trigger_right_active = !not_pressed axis_signal.emit(jev.axis, trigger_right_active, jev.device) trigger_right = value func handle_button(jev : InputEventJoypadButton) -> void: button_signal.emit(jev.button_index, jev.pressed, jev.device) func get_left_stick() -> Vector2: return left_stick func get_right_stick() -> Vector2: return right_stick func get_left_trigger() -> float: return trigger_left func get_right_trigger() -> float: return trigger_right @onready var devices_state : Dictionary[int, GameControllerState] = {} func get_left_stick(device : int = 1) -> Vector2: return devices_state[device].get_left_stick() if devices_state.has(device) else Vector2.ZERO func get_right_stick(device : int = 1) -> Vector2: return devices_state[device].get_right_stick() if devices_state.has(device) else Vector2.ZERO func get_left_trigger(device : int = 1) -> float: return devices_state[device].get_left_trigger() if devices_state.has(device) else -1. func get_right_trigger(device : int = 1) -> float: return devices_state[device].get_right_trigger() if devices_state.has(device) else -1. func _input(event : InputEvent) -> void: if event is InputEventJoypadMotion: # Passive action => Update the stick and trigger state var jev : InputEventJoypadMotion = event as InputEventJoypadMotion if devices_state.has(jev.device): devices_state[jev.device].handle_motion(jev) elif event is InputEventJoypadButton: # Active action => Trigger action var jev : InputEventJoypadButton = event as InputEventJoypadButton if devices_state.has(jev.device): devices_state[jev.device].handle_button(jev)
or share this direct link: