@tool extends Node2D class_name ScreenRatioRect # =============================== # Internal State # =============================== var _rect: Rect2 = Rect2() var _line_color: Color = Color(0.2, 0.9, 0.4, 0.9) var _line_width: float = 2.0 var _target_node: Node2D = null var _target_screen_pos: Vector2 = Vector2.ZERO var _target_radius: float = 6.0 var _target_color: Color = Color(1, 0.3, 0.3, 0.9) func _process(_delta: float) -> void: if Engine.is_editor_hint(): return if _target_node: _update_target_screen_pos() queue_redraw() # =============================== # Public API # =============================== ## 通过屏幕比例设置(0~1) func set_ratio(ratio: Vector2) -> void: var viewport_size := get_viewport_rect().size var size := viewport_size * ratio var pos := (viewport_size - size) * 0.5 set_rect(Rect2(pos, size)) ## 直接设置屏幕空间 Rect func set_rect(rect: Rect2) -> void: _rect = rect queue_redraw() ## 设置绘制风格 func set_style(color: Color, width: float = 2.0) -> void: _line_color = color _line_width = width queue_redraw() ## 设置追踪点 func set_target_node(node: Node2D) -> void: _target_node = node _update_target_screen_pos() queue_redraw() ## 更新targetnode在屏幕的位置 func _update_target_screen_pos() -> void: if not _target_node: return _target_screen_pos = \ _target_node.get_global_transform_with_canvas().get_origin() ## 可选:快速隐藏 / 显示 func clear() -> void: _target_node = null _rect = Rect2() queue_redraw() # =============================== # Draw # =============================== func _draw() -> void: if _rect.size == Vector2.ZERO: return var left := _rect.position.x var right := _rect.position.x + _rect.size.x var top := _rect.position.y var bottom := _rect.position.y + _rect.size.y var vp_size := get_viewport_rect().size # 上边线 draw_line( Vector2(0, top), Vector2(vp_size.x, top), _line_color, _line_width ) # 下边线 draw_line( Vector2(0, bottom), Vector2(vp_size.x, bottom), _line_color, _line_width ) # 左边线 draw_line( Vector2(left, 0), Vector2(left, vp_size.y), _line_color, _line_width ) # 右边线 draw_line( Vector2(right, 0), Vector2(right, vp_size.y), _line_color, _line_width ) ##绘制角色位置锚点 if _target_node: draw_circle(_target_screen_pos, _target_radius, _target_color)