class_name TrackRider extends Node2D @export var attached_entity: Node2D = null @export_range(1, 8, 1) var speed := 2 @export_enum("Forward", "Backward") var direction := 0 var velocity := Vector2.ZERO var last_position := Vector2.ZERO var direction_vector := Vector2i.ZERO var current_track: Track = null var track_idx := -1 var can_attach := true var travelling_on_rail := false func _ready() -> void: start() await get_tree().physics_frame if attached_entity != null: attach_to_joint(attached_entity) func start() -> void: current_track = null track_idx = -1 func check_for_entities() -> void: for i in $Hitbox.get_overlapping_bodies(): print(i) if i.has_node("TrackJoint"): attach_to_joint(i) return for i in $Hitbox.get_overlapping_areas(): print(i) if i.owner.has_node("TrackJoint"): attach_to_joint(i.owner) return func _physics_process(delta: float) -> void: if attached_entity == null: check_for_entities() return if travelling_on_rail == false: velocity.y += 10 global_position += velocity * delta check_for_rail() last_position = global_position func attach_to_joint(node: Node2D) -> void: var joint = node.get_node("TrackJoint") joint.is_attached = true if joint.movement_node != null: joint.movement_node.active = false joint.attached.emit() elif joint.disable_physics: node.set_physics_process(false) joint.rider = self node.physics_interpolation_mode = Node.PHYSICS_INTERPOLATION_MODE_OFF node.reparent($Joint, false) node.position = joint.offset attached_entity = node func check_for_rail() -> void: if travelling_on_rail == false and can_attach: for i in $Hitbox.get_overlapping_areas(): if i.get_parent() is TrackPiece and i.get_parent().owner != current_track: var piece: TrackPiece = i.get_parent() if piece.owner.length <= 0: continue global_position = piece.global_position travelling_on_rail = true current_track = piece.owner track_idx = piece.idx if track_idx >= current_track.path.size(): direction = 1 if direction == 1: track_idx -= 1 track_idx = clamp(track_idx, 0, current_track.path.size() - 1) if travelling_on_rail: direction_vector = current_track.path[track_idx] * [1, -1][direction] if current_track != null: move_tween(Vector2(direction_vector)) func move_tween(new_direction := Vector2.ZERO) -> void: var tween = create_tween() tween.tween_property(self, "global_position", global_position + (new_direction * 16), float(1.0 if new_direction.is_normalized() else 1.414) / (speed * 2)) await tween.finished track_idx += [1, -1][direction] if track_idx >= current_track.length and direction == 0: track_idx = current_track.length - 1 if current_track.end_point == 0: direction = 1 else: detach_from_rail() return if track_idx < 0 and direction == 1: track_idx = 0 if current_track.start_point == 0: direction = 0 else: detach_from_rail() return check_for_rail() func detach_from_rail() -> void: can_attach = false travelling_on_rail = false track_idx = -1 velocity = direction_vector * speed * 48 await get_tree().create_timer(0.1, false).timeout can_attach = true