tli/scripts/interactable.gd

59 lines
1.5 KiB
GDScript

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