Init
This commit is contained in:
97
scripts/click_manager.gd
Normal file
97
scripts/click_manager.gd
Normal file
@@ -0,0 +1,97 @@
|
||||
extends Node
|
||||
|
||||
signal camera_move_requested(destination: Transform3D)
|
||||
signal back_requested
|
||||
|
||||
var _hovered: Clickable = null
|
||||
|
||||
|
||||
func get_camera() -> Camera3D:
|
||||
return get_viewport().get_camera_3d()
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
back_requested.connect(_on_back_requested)
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
_update_hover(get_viewport().get_mouse_position())
|
||||
|
||||
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event is InputEventMouseButton:
|
||||
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
|
||||
_raycast_click(get_viewport().get_mouse_position())
|
||||
|
||||
if event is InputEventKey and event.pressed and not event.echo:
|
||||
if event.keycode == KEY_ESCAPE or event.keycode == KEY_BACKSPACE:
|
||||
request_back()
|
||||
|
||||
|
||||
func _on_back_requested() -> void:
|
||||
var cam = get_camera()
|
||||
if cam and cam.has_method("go_back"):
|
||||
cam.go_back()
|
||||
|
||||
|
||||
func request_back() -> void:
|
||||
back_requested.emit()
|
||||
|
||||
|
||||
func _update_hover(screen_pos: Vector2) -> void:
|
||||
var clickable = _raycast_find_clickable(screen_pos)
|
||||
|
||||
if clickable != _hovered:
|
||||
_hovered = clickable
|
||||
|
||||
if _hovered:
|
||||
CursorManager.set_cursor(_hovered.cursor_hint)
|
||||
else:
|
||||
CursorManager.reset()
|
||||
|
||||
|
||||
func _raycast_click(screen_pos: Vector2) -> void:
|
||||
var clickable = _raycast_find_clickable(screen_pos)
|
||||
|
||||
if clickable:
|
||||
clickable.on_clicked(_raycast_position(screen_pos))
|
||||
|
||||
|
||||
func _raycast_find_clickable(screen_pos: Vector2) -> Clickable:
|
||||
var result = _raycast(screen_pos)
|
||||
if result.is_empty():
|
||||
return null
|
||||
|
||||
return _find_clickable_in(result.collider)
|
||||
|
||||
|
||||
func _raycast_position(screen_pos: Vector2) -> Vector3:
|
||||
var result = _raycast(screen_pos)
|
||||
return result.get("position", Vector3.ZERO)
|
||||
|
||||
|
||||
func _raycast(screen_pos: Vector2) -> Dictionary:
|
||||
var camera = get_camera()
|
||||
if not camera:
|
||||
return {}
|
||||
|
||||
var space = camera.get_world_3d().direct_space_state
|
||||
var origin = camera.project_ray_origin(screen_pos)
|
||||
var end = origin + camera.project_ray_normal(screen_pos) * 100.0
|
||||
|
||||
var query = PhysicsRayQueryParameters3D.create(origin, end)
|
||||
return space.intersect_ray(query)
|
||||
|
||||
|
||||
func _find_clickable_in(node: Node) -> Clickable:
|
||||
while node:
|
||||
var c = node.find_child("Clickable", false, false)
|
||||
if c:
|
||||
return c as Clickable
|
||||
node = node.get_parent()
|
||||
|
||||
return null
|
||||
|
||||
|
||||
func request_camera_move(destination: Transform3D) -> void:
|
||||
camera_move_requested.emit(destination)
|
||||
Reference in New Issue
Block a user