72 lines
1.9 KiB
GDScript
72 lines
1.9 KiB
GDScript
extends MeshInstance3D
|
|
class_name TrainBody
|
|
|
|
signal speed_changed(new_speed: float)
|
|
signal rail_switched(old_rail: Path3D, new_rail: Path3D)
|
|
|
|
@export_group("Train")
|
|
@export var base_speed: float = 15.0
|
|
@export var max_speed: float = 50.0
|
|
@export var min_speed: float = 3.0
|
|
@export var acceleration: float = 12.0
|
|
@export var rail_a: Path3D
|
|
@export var rail_b: Path3D
|
|
|
|
var current_follower: PathFollow3D
|
|
var current_rail: Path3D
|
|
var current_speed: float = 15.0
|
|
|
|
func _ready() -> void:
|
|
current_speed = base_speed
|
|
switch_to_rail(rail_a)
|
|
|
|
|
|
func _process(delta: float) -> void:
|
|
_handle_input(delta)
|
|
current_follower.progress += current_speed * delta
|
|
|
|
|
|
func _handle_input(delta: float) -> void:
|
|
if Input.is_action_pressed("speed_up"):
|
|
current_speed = min(current_speed + acceleration * delta, max_speed)
|
|
speed_changed.emit(current_speed)
|
|
elif Input.is_action_pressed("speed_down"):
|
|
current_speed = max(current_speed - acceleration * delta, min_speed)
|
|
speed_changed.emit(current_speed)
|
|
|
|
|
|
func get_speed() -> float:
|
|
return current_speed
|
|
|
|
|
|
func switch_to_rail(new_rail: Path3D) -> void:
|
|
if new_rail == current_rail:
|
|
return
|
|
|
|
current_rail = new_rail
|
|
current_follower = new_rail.get_node("TrainEngine") as PathFollow3D
|
|
|
|
var closest_offset = find_closest_point_on_path(new_rail, global_position)
|
|
current_follower.progress = closest_offset
|
|
|
|
|
|
func find_closest_point_on_path(path: Path3D, point: Vector3) -> float:
|
|
var curve = path.curve
|
|
var closest_offset = 0.0
|
|
var min_distance = INF
|
|
|
|
var length = curve.get_baked_length()
|
|
var steps = 100 # Più alto = più preciso ma più lento
|
|
|
|
for i in range(steps + 1):
|
|
var offset = (float(i) / steps) * length
|
|
# Trasforma il punto locale della curva in coordinate globali
|
|
var path_point = path.global_transform * curve.sample_baked(offset)
|
|
var dist = point.distance_to(path_point)
|
|
|
|
if dist < min_distance:
|
|
min_distance = dist
|
|
closest_offset = offset
|
|
|
|
return closest_offset
|