@tool @icon("uid://bsdmq0essfmpk") class_name CameraAnchor extends Node2D @export_group("Anchor Config") ##该priority不会直接修改Anchor的priority,只用作初始化 @export var priority: int = 0 ##此Anchor是否有效 @export var enabled: bool = true ##是否要存在相機過渡時間 @export var use_blend: bool = true ##過度時間 @export var blend_time: float = 0.3 @export_group("Camera Config") @export_subgroup("Sizing") @export var zoom: Vector2 = Vector2.ONE: set(value): zoom = value if Engine.is_editor_hint(): queue_redraw() @export_subgroup("Limit") @export var use_camera_limit: bool = false: set(value): use_camera_limit = value if Engine.is_editor_hint(): queue_redraw() @export var limit_top: int = -10000000: set(value): limit_top = value if Engine.is_editor_hint(): queue_redraw() @export var limit_bottom: int = 10000000: set(value): limit_bottom = value if Engine.is_editor_hint(): queue_redraw() @export var limit_left: int = -10000000: set(value): limit_left = value if Engine.is_editor_hint(): queue_redraw() @export var limit_right: int = 10000000: set(value): limit_right = value if Engine.is_editor_hint(): queue_redraw() @export_subgroup("Follow") @export var follow_player: bool = false var _pcam_manager: Node = null ## 编辑器预览面板设置 @export_group("Editor Preview") @export var show_camera_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 @export var show_limit_preview: bool = true @export var limit_preview_color: Color = Color(0.9, 0.3, 0.3, 0.8) @export var limit_preview_line_width: float = 2.0 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(): _pcam_manager = Engine.get_singleton("PhantomCameraManager") return CameraSystem.register_anchor(self) func _exit_tree() -> void: if Engine.is_editor_hint(): _pcam_manager = null return CameraSystem.unregister_anchor(self) func _draw() -> void: if not Engine.is_editor_hint(): return if show_camera_preview and is_instance_valid(_pcam_manager): draw_rect( _camera_frame_rect_like_phantom(), preview_color, false, preview_line_width ) if show_limit_preview and use_camera_limit: draw_rect( _camera_limit_rect(), limit_preview_color, false, limit_preview_line_width ) func _camera_limit_rect() -> Rect2: var pos := Vector2(limit_left, limit_top) var size := Vector2( limit_right - limit_left, limit_bottom - limit_top ) return Rect2(pos, size) 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