class_name SinglePlayerLogicalEventMapper extends Node signal on_action(action_id : int, activated : bool) @export var deadzone : float = 0.1 @export var mapping : Dictionary[int, EventDescriptor] = {} : set(value) : mapping = value _remap() var joybutton_press_event : Dictionary[JoyButton, int] = {} var joybutton_release_event : Dictionary[JoyButton, int] = {} var joyaxis_press_event : Dictionary[JoyAxis, int] = {} var joyaxis_release_event : Dictionary[JoyAxis, int] = {} var last_joy_axis_values : Array[float] var mousebutton_press_event : Dictionary[MouseButton, int] = {} var mousebutton_release_event : Dictionary[MouseButton, int] = {} var key_press_event : Dictionary[int, int] = {} var key_release_event : Dictionary[int, int] = {} func _ready() -> void: last_joy_axis_values = [] last_joy_axis_values.resize(JOY_AXIS_MAX) last_joy_axis_values.fill(0.) func _remap() -> void: joybutton_press_event.clear() joybutton_release_event.clear() joyaxis_press_event.clear() joyaxis_release_event.clear() mousebutton_press_event.clear() mousebutton_release_event.clear() key_press_event.clear() key_release_event.clear() for m in mapping: var action_id : int = m var descriptor : EventDescriptor = mapping[action_id] while descriptor != null: _add_mapping(action_id, descriptor) descriptor = descriptor.alternate func _add_mapping(action_id : int, descriptor : EventDescriptor) -> void: var toggle : bool = descriptor.toggle_event var pressed : bool = descriptor.is_pressed match descriptor.kind: EventDescriptor.EventMedia.JOYSTICK: if descriptor.joy_button != JOY_BUTTON_INVALID: var button : JoyButton = descriptor.joy_button if toggle: joybutton_press_event[button] = action_id joybutton_release_event[button] = action_id elif pressed: joybutton_press_event[button] = action_id else: joybutton_release_event[button] = action_id elif descriptor.joy_axis != JOY_AXIS_INVALID: var axis : JoyAxis = descriptor.joy_axis if toggle: joyaxis_press_event[axis] = action_id joyaxis_release_event[axis] = action_id elif pressed: joyaxis_press_event[axis] = action_id else: joyaxis_release_event[axis] = action_id EventDescriptor.EventMedia.KEYBOARD: var key : int = descriptor.key_code if descriptor.key_alt_modifier: key += KEY_MASK_ALT if descriptor.key_ctrl_modifier: key += KEY_MASK_CTRL if descriptor.key_shift_modifier: key += KEY_MASK_SHIFT if descriptor.key_meta_modifier: key += KEY_MASK_META if toggle: key_press_event[key] = action_id key_release_event[key] = action_id elif pressed: key_press_event[key] = action_id else: key_release_event[key] = action_id EventDescriptor.EventMedia.MOUSE: if descriptor.mouse_button != MOUSE_BUTTON_NONE: var button : MouseButton = descriptor.mouse_button if toggle: mousebutton_press_event[button] = action_id mousebutton_release_event[button] = action_id elif pressed: mousebutton_press_event[button] = action_id else: mousebutton_release_event[button] = action_id _: pass func _input(event : InputEvent) -> void: match event.get_class(): "InputEventKey": var kev : InputEventKey = event as InputEventKey if not kev.echo: var dict : Dictionary[int, int] = key_press_event if kev.pressed else key_release_event var key : int = kev.get_keycode_with_modifiers() if dict.has(key): on_action.emit(dict[key], kev.pressed) "InputEventMouseButton": var mev : InputEventMouseButton = event as InputEventMouseButton var dict : Dictionary[MouseButton, int] = mousebutton_press_event if mev.pressed else mousebutton_release_event if dict.has(mev.button_index): on_action.emit(dict[mev.button_index], mev.pressed) "InputEventJoypadButton": var jev : InputEventJoypadButton = event as InputEventJoypadButton var dict : Dictionary[JoyButton, int] = joybutton_press_event if jev.pressed else joybutton_release_event if dict.has(jev.button_index): on_action.emit(dict[jev.button_index], jev.pressed) "InputEventJoypadMotion": var jev : InputEventJoypadMotion = event as InputEventJoypadMotion var value : float = 0. if abs(jev.axis_value) < deadzone else jev.axis_value var activated : bool = not is_zero_approx(value) var last_activated : bool = not is_zero_approx(last_joy_axis_values[jev.axis]) last_joy_axis_values[jev.axis] = value if activated != last_activated: var dict : Dictionary[JoyAxis, int] = joyaxis_press_event if activated else joyaxis_release_event if dict.has(jev.axis): on_action.emit(dict[jev.axis], activated) _: pass
or share this direct link: