immersive-home/content/raycast.gd

97 lines
2.1 KiB
GDScript3
Raw Normal View History

2023-10-23 02:58:18 +03:00
extends Node3D
@onready var _controller := XRHelpers.get_xr_controller(self)
@export var ray: RayCast3D
# Called when the node enters the scene tree for the first time.
func _ready():
2023-11-05 14:59:33 +02:00
_controller.button_pressed.connect(_on_button_pressed)
_controller.button_released.connect(_on_button_released)
2023-10-23 02:58:18 +03:00
2023-11-05 14:59:33 +02:00
var _last_collided: Object = null
var _is_pressed := false
var _is_grabbed := false
var _moved := false
var _click_point := Vector3.ZERO
func _physics_process(delta):
_handle_enter_leave()
_handle_move()
func _get_event_data():
return {
"controller": _controller,
"ray": ray,
}
func _handle_move():
2023-11-05 22:32:50 +02:00
if _is_pressed == false && _is_grabbed == false:
return
2023-11-05 14:59:33 +02:00
var distance = ray.get_collision_point().distance_to(_click_point)
2023-11-05 15:09:19 +02:00
var collider = ray.get_collider()
2023-11-05 14:59:33 +02:00
2023-11-05 22:32:50 +02:00
if distance > 0.02:
2023-11-05 14:59:33 +02:00
if _is_pressed:
2023-11-05 15:09:19 +02:00
_call_fn(collider, "_on_press_move")
2023-11-05 14:59:33 +02:00
_moved = true
if _is_grabbed:
2023-11-05 15:09:19 +02:00
_call_fn(collider, "_on_grab_move")
2023-11-05 14:59:33 +02:00
_moved = true
func _handle_enter_leave():
var collider = ray.get_collider()
if collider == _last_collided:
return
2023-11-05 15:09:19 +02:00
_call_fn(collider, "_on_ray_enter")
_call_fn(_last_collided, "_on_ray_leave")
2023-11-05 14:59:33 +02:00
_last_collided = collider
2023-10-23 02:58:18 +03:00
func _on_button_pressed(button):
2023-11-05 14:59:33 +02:00
var collider = ray.get_collider()
if collider == null:
2023-10-23 02:58:18 +03:00
return
2023-11-05 14:59:33 +02:00
match button:
"trigger_click":
_is_pressed = true
_click_point = ray.get_collision_point()
2023-11-05 15:09:19 +02:00
_call_fn(collider, "_on_press_down")
2023-11-05 14:59:33 +02:00
"grip_click":
_is_grabbed = true
_click_point = ray.get_collision_point()
2023-11-05 15:09:19 +02:00
_call_fn(collider, "_on_grab_down")
2023-11-05 14:59:33 +02:00
func _on_button_released(button):
2023-10-23 02:58:18 +03:00
var collider = ray.get_collider()
if collider == null:
return
2023-11-05 14:59:33 +02:00
match button:
"trigger_click":
if _is_pressed:
if _moved == false:
2023-11-05 15:09:19 +02:00
_call_fn(collider, "_on_click")
_call_fn(collider, "_on_press_up")
2023-11-05 14:59:33 +02:00
_is_pressed = false
_moved = false
"grip_click":
if _is_grabbed:
2023-11-05 15:09:19 +02:00
_call_fn(collider, "_on_grab_up")
2023-11-05 14:59:33 +02:00
_is_grabbed = false
_moved = false
2023-10-23 02:58:18 +03:00
2023-11-05 15:09:19 +02:00
func _call_fn(collider: Object, fn_name: String):
2023-11-05 22:32:50 +02:00
if collider != null:
if collider.has_method(fn_name):
collider.call(fn_name, _get_event_data())
for child in collider.get_children():
if child is Function:
_call_fn(child, fn_name)