@tool extends Node2D @export var velocity := 0.1 @export var remote_node: Node2D: set(val): remote_node = val if is_node_ready(): if remote_node: remote_transform.remote_path = remote_node.get_path() else: remote_transform.remote_path = "" @export var area_size := Vector2(400, 50): set(val): area_size = val queue_redraw() @export var gizmo_outline_color := Color(0.5, 0.3, 0.4, 0.8): set(val): gizmo_outline_color = val queue_redraw() @onready var remote_transform := $RemoteTransform2D as RemoteTransform2D func _draw() -> void: remote_transform.remote_path = remote_node.get_path() if Engine.is_editor_hint(): # draw gizmo var area_rect = Rect2(Vector2.ZERO, area_size) # fill var fill_color = gizmo_outline_color fill_color.a = 0.4 draw_rect(area_rect, fill_color) # outline draw_rect(area_rect, gizmo_outline_color, false, 1.0) # 最多保持 4 个点; 先生成两个在左侧,再生成两个在右侧,然后再回到左侧,以此循环,形成左右摇摆的闭合路径 var bezier_points = [] var current_position = Vector2.ZERO var weight := 0.0 func _ready() -> void: # init points for i in range(4): bezier_points.append(_rand_point()) func _new_point() -> void: # remove the first point bezier_points.remove_at(0) # add a new point bezier_points.append(_rand_point()) var _generated_points = -1 func _rand_point() -> Vector2: _generated_points += 1 # upleft,mid,downright,upright,mid,downleft,... match _generated_points % 6: 0: _generated_points = 0 # upleft return Vector2( randf_range(0, area_size.x * 0.3), randf_range(area_size.y * 0.6, area_size.y) ) 1: # upleft to center return Vector2( randf_range(area_size.x * 0.4, area_size.x * 0.6), randf_range(area_size.y * 0.3, area_size.y * 0.7) ) 2: # center to downright return Vector2( randf_range(area_size.x * 0.7, area_size.x), randf_range(0, area_size.y * 0.4) ) 3: # downright to upright return Vector2( randf_range(area_size.x * 0.7, area_size.x), randf_range(area_size.y * 0.6, area_size.y) ) 4: # upright to center return Vector2( randf_range(area_size.x * 0.4, area_size.x * 0.6), randf_range(area_size.y * 0.3, area_size.y * 0.7) ) _: # center to downleft return Vector2(randf_range(0, area_size.x * 0.3), randf_range(0, area_size.y * 0.4)) # 从 bezier_points 中取出 4 个点,然后进行贝塞尔曲线插值 # 设置到 remote_transform 的 position 与 rotation # 速度为 velocity,权重为 weight func _process(delta: float) -> void: if Engine.is_editor_hint(): return weight += velocity * delta if weight >= 1.0: weight = 0.0 _new_point() var p0 = bezier_points[0] var p1 = bezier_points[1] var p2 = bezier_points[2] var p3 = bezier_points[3] var p = p1.cubic_interpolate(p2, p0, p3, weight) # var p = p1.bezier_interpolate(p0, p3, p2, weight) remote_transform.position = p # bezier 插值获得角度 remote_transform.rotation = lerp_angle(remote_transform.rotation, p1.angle_to(p2), delta)