extends CharacterBody3D class_name Interactable ## A base interactable object that can be hovered over and clicked on. ## When releasing the mouse button, how many pixels away from the click. ## position the cursor has to be for it to be considered a click and not drag. const MAX_CLICK_RELEASE_DISTANCE: float = 15 var _hovered: bool = false var _mouse_over: bool = false var _can_interact: bool = true var _click_start_position: Vector2 = Vector2.ZERO @onready var hover_indicator: VisualInstance3D = $HoverIndicator func _ready() -> void: assert(hover_indicator != null, "hover_indicator missing!") mouse_entered.connect(_on_mouse_entered) mouse_exited.connect(_on_mouse_exited) func _process(_delta: float) -> void: if not _can_interact: _hovered = false return _hovered = HoveringManager.hovered_node == self and _mouse_over hover_indicator.visible = _hovered func _input(event: InputEvent) -> void: if not _can_interact: return if event is InputEventMouseButton and _hovered: var button_event := event as InputEventMouseButton if button_event.button_index != MOUSE_BUTTON_LEFT: return if button_event.pressed: _click_start_position = button_event.position else: if ( (button_event.position - _click_start_position).length() < MAX_CLICK_RELEASE_DISTANCE ): _click() func _click() -> void: print(self, " clicked!") func _on_mouse_entered() -> void: _mouse_over = true func _on_mouse_exited() -> void: _mouse_over = false