64 lines
1.7 KiB
GDScript
64 lines
1.7 KiB
GDScript
class_name LoadingZone extends Area3D
|
|
|
|
const FLOOR_CHECK_DISTANCE: float = 100.0
|
|
const FLOOR_ANTICLIP: float = 0.25
|
|
const RAYCAST_ANTICLIP: float = 5.0
|
|
const AREA_ANTICLIP: float = 1.0
|
|
const SCENE_START_TIMEOUT: float = 1.0
|
|
|
|
enum ActiveState {
|
|
DISABLED,
|
|
ENABLED,
|
|
DROPOFF_ONLY
|
|
}
|
|
|
|
@export var active_state := ActiveState.ENABLED
|
|
|
|
@onready var bounds := (
|
|
$'CollisionShape3D' as CollisionShape3D
|
|
).shape as BoxShape3D
|
|
|
|
func dropoff_site() -> Transform3D:
|
|
var raycast := PhysicsRayQueryParameters3D.new()
|
|
raycast.from = (
|
|
global_position + basis.z*(bounds.size.z/2.0 + AREA_ANTICLIP) +
|
|
basis.y*RAYCAST_ANTICLIP
|
|
)
|
|
raycast.to = raycast.from - basis.y*FLOOR_CHECK_DISTANCE
|
|
var chk := get_world_3d().direct_space_state.intersect_ray(raycast)
|
|
return Transform3D(basis.orthonormalized(), (
|
|
global_position if chk.is_empty()
|
|
else chk.position + basis.y*FLOOR_ANTICLIP
|
|
))
|
|
|
|
func dropoff(what: Node3D, use_model_front: bool = true) -> void:
|
|
what.transform = dropoff_site()
|
|
if use_model_front:
|
|
what.basis = what.basis.rotated(what.basis.y, PI)
|
|
|
|
func pickup(node: Node) -> void:
|
|
if (
|
|
active_state == ActiveState.ENABLED and
|
|
PlayerControl.enabled() and
|
|
node == PlayerControl.get_runner()
|
|
):
|
|
Storyboard.try_follow_map_connection(name)
|
|
|
|
func enable() -> void:
|
|
if active_state != ActiveState.DROPOFF_ONLY:
|
|
active_state = ActiveState.ENABLED
|
|
|
|
func disable() -> void:
|
|
if active_state != ActiveState.DROPOFF_ONLY:
|
|
active_state = ActiveState.DISABLED
|
|
|
|
func enabled() -> bool:
|
|
return bool(active_state == ActiveState.ENABLED)
|
|
|
|
func _ready() -> void:
|
|
_connect_pickup_after_timeout.call_deferred()
|
|
|
|
func _connect_pickup_after_timeout() -> void:
|
|
await Wait.seconds(SCENE_START_TIMEOUT)
|
|
body_entered.connect(pickup)
|