immersive-home/app/content/system/raycast/raycast.gd

62 lines
1.8 KiB
GDScript3
Raw Normal View History

2023-11-22 02:44:07 +02:00
extends RayCast3D
2024-03-17 19:04:20 +02:00
const Pointer = preload ("res://lib/utils/pointer/pointer.gd")
const Initiator = preload ("res://lib/utils/pointer/initiator.gd")
2023-11-27 01:23:19 +02:00
2023-11-26 14:48:27 +02:00
@onready var cursor: Node3D = $Cursor
@onready var decal: Decal = $Decal
2023-11-22 02:44:07 +02:00
@export var is_right: bool = true
2023-11-26 14:48:27 +02:00
@export var with_decal: bool = false
2023-11-22 02:44:07 +02:00
2023-11-27 01:23:19 +02:00
@onready var pointer: Pointer
2024-03-17 19:04:20 +02:00
@onready var visual_ray: MeshInstance3D = $Ray
2023-11-22 02:44:07 +02:00
2023-11-27 01:23:19 +02:00
var _event_type_map = {
"trigger_click": Initiator.EventType.TRIGGER,
"grip_click": Initiator.EventType.GRIP,
}
2023-11-22 02:44:07 +02:00
func _ready():
2023-11-27 01:23:19 +02:00
var initiator = Initiator.new()
initiator.type = Initiator.Type.CONTROLLER_RIGHT if is_right else Initiator.Type.CONTROLLER_LEFT
initiator.node = get_parent()
assert(get_parent() is XRController3D, "Parent must be XRController3D")
pointer = Pointer.new(initiator, self)
add_child(pointer)
get_parent().button_pressed.connect(func(button: String):
if _event_type_map.has(button):
initiator.on_press.emit(_event_type_map[button])
)
get_parent().button_released.connect(func(button: String):
if _event_type_map.has(button):
initiator.on_release.emit(_event_type_map[button])
)
2023-11-22 02:44:07 +02:00
func _physics_process(_delta):
2023-11-26 14:48:27 +02:00
_handle_cursor()
func _handle_cursor():
var collider = get_collider()
2024-03-17 19:04:20 +02:00
var distance = get_collision_point().distance_to(global_position)
2023-11-26 14:48:27 +02:00
if collider == null:
cursor.visible = false
2024-03-17 19:04:20 +02:00
visual_ray.visible = true
visual_ray.scale.y = 1
2023-11-26 14:48:27 +02:00
if with_decal: decal.visible = true
return
2024-03-17 19:04:20 +02:00
if distance < 0.15:
visual_ray.visible = false
else:
visual_ray.visible = true
visual_ray.scale.y = clamp(distance * 2 - 0.1, 0.15, 1)
2023-11-26 14:48:27 +02:00
cursor.visible = true
decal.visible = false
cursor.global_transform.origin = get_collision_point() + get_collision_normal() * 0.001 # offset to avoid z-fighting
cursor.global_transform.basis = Basis.looking_at(get_collision_normal(), Vector3.UP)