godot-plateformer/_shared/camera/CameraAnchor.gd

92 lines
2.1 KiB
GDScript3
Raw Normal View History

2026-01-06 16:19:08 +08:00
@tool
class_name CameraAnchor extends Node2D
## 该priority不会直接修改Anchor的priority
@export var priority: int = 0
@export var enabled: bool = true
@export var blend_time: float = 0.3
2026-01-08 15:53:30 +08:00
@export_group("Phantom Camera Config")
@export var zoom: Vector2 = Vector2.ONE:
set(value):
zoom = value
if Engine.is_editor_hint():
queue_redraw()
var _pcam_manager: Node = null
# =====================================================
# ================ Editor Preview =====================
# =====================================================
## 编辑器预览面板设置
@export_group("Editor Preview")
@export var show_frame_preview: bool = true
@export var preview_color: Color = Color(0.2, 0.9, 0.4, 0.8)
@export var preview_line_width: float = 2.0
2026-01-06 16:19:08 +08:00
var _priority: int :
set(value):
if _priority != value:
_priority = value
on_priority_change.emit(_priority, self)
signal on_priority_change(_priority:int, anchor: CameraAnchor)
func _ready() -> void:
if not Engine.is_editor_hint():
_runtime_ready()
func _enter_tree() -> void:
if Engine.is_editor_hint():
2026-01-08 15:53:30 +08:00
_pcam_manager = Engine.get_singleton("PhantomCameraManager")
2026-01-06 16:19:08 +08:00
return
2026-01-08 15:53:30 +08:00
2026-01-06 16:19:08 +08:00
CameraSystem.register_anchor(self)
func _exit_tree() -> void:
if Engine.is_editor_hint():
2026-01-08 15:53:30 +08:00
_pcam_manager = null
2026-01-06 16:19:08 +08:00
return
CameraSystem.unregister_anchor(self)
2026-01-08 15:53:30 +08:00
func _draw() -> void:
if not Engine.is_editor_hint():
return
if not show_frame_preview:
return
if not is_instance_valid(_pcam_manager):
return
draw_rect(
_camera_frame_rect_like_phantom(),
preview_color,
false,
preview_line_width
)
func _camera_frame_rect_like_phantom() -> Rect2:
# PhantomCamera 使用的是 manager.screen_size
var screen_size: Vector2 = _pcam_manager.screen_size
var z := zoom
z.x = maxf(z.x, 0.001)
z.y = maxf(z.y, 0.001)
var size := Vector2(
screen_size.x / z.x,
screen_size.y / z.y
)
# PhantomCamera以自身为中心
return Rect2(-size * 0.5, size)
func _runtime_ready() -> void:
_priority = priority
func push_camera() -> void:
CameraSystem.reset_all_camera_priority()
_priority = 1000
func pop_camera() -> void:
_priority = 0