tool extends Node2D const DEBUG_COLOR := Color(0.4, 0.2, 0.6, 0.75) export var size: float = 8.0 setget _set_size export var speed: float = 20.0 export var point_a := Vector2.ZERO setget _set_point_a export var point_b := Vector2.ZERO setget _set_point_b export (float, 0.0, 1.0, 0.1) var start_position: float = 0.0 setget _set_start_position export var start_reversed: bool = false onready var body: KinematicBody2D = $Body onready var sprite: Sprite = $"%Sprite" var _previous_position: Vector2 func _ready() -> void: if Engine.editor_hint: return var distance := point_a.distance_to(point_b) var start_target := point_a if start_reversed else point_b var end_target := point_b if start_reversed else point_a var start_weight := start_position if start_reversed else 1.0 - start_position var tween := create_tween() tween.stop() tween.set_process_mode(Tween.TWEEN_PROCESS_PHYSICS) tween.set_loops() tween.tween_property(body, "position", end_target, distance / speed) tween.tween_property(body, "position", start_target, distance / speed) var start_tween := create_tween() start_tween.set_process_mode(Tween.TWEEN_PROCESS_PHYSICS) start_tween.tween_property(body, "position", start_target, start_weight * distance / speed) start_tween.tween_callback(tween, "play") _previous_position = body.global_position func _physics_process(delta: float) -> void: if Engine.editor_hint: return if (body.global_position.y - _previous_position.y) < 0.0 and speed >= 40.0: sprite.position.y = -1.0 else: sprite.position.y = 0.0 _previous_position = body.global_position func _set_size(value: float) -> void: size = value get_node("%Sprite").region_rect.size.x = size var segment = get_node("%CollisionShape").shape as SegmentShape2D segment.a.x = size * -0.5 segment.b.x = size * 0.5 func _set_start_position(value: float) -> void: start_position = value if Engine.editor_hint: get_node("Body").position = lerp(point_a, point_b, start_position) func _set_point_a(value: Vector2) -> void: point_a = value if Engine.editor_hint: _update_positions() func _set_point_b(value: Vector2) -> void: point_b = value if Engine.editor_hint: _update_positions() func _update_positions() -> void: if point_a == point_b: _set_start_position(0.0) else: var closest_point := Geometry.get_closest_point_to_segment_2d(get_node("Body").position, point_a, point_b) _set_start_position(point_a.distance_to(closest_point) / point_a.distance_to(point_b)) property_list_changed_notify() update() func _draw() -> void: if Engine.editor_hint: draw_line(point_a, point_b, DEBUG_COLOR, 1.01)