115 lines
2.4 KiB
GDScript3
115 lines
2.4 KiB
GDScript3
|
|
@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)
|