@tool extends Node class_name CameraPointer const _CONSTANTS := preload("res://addons/reedcamera/_data/CameraSystemConst.gd") var _camera: Camera2D var _editor_valid := false var _runtime_registered := false var _warned := false var _final_offset := Vector2.ZERO var _base_position: Vector2 func _enter_tree() -> void: if Engine.is_editor_hint(): call_deferred("_editor_verify") func _exit_tree() -> void: if Engine.is_editor_hint(): return _request_unregister() func _process(delta: float) -> void: if Engine.is_editor_hint(): return if not _camera: return _update_base_position() _update_camera_offset() _apply_camera_transform() func _update_base_position(): for child in get_children(): if child.has_method("get_base_position"): _base_position = child.get_base_position() return # fallback _base_position = _camera.global_position func _update_camera_offset(): var offset := Vector2.ZERO for child in get_children(): if child.has_method("get_camera_offset"): offset += child.get_camera_offset() _final_offset = offset func _apply_camera_transform(): _camera.global_position = _base_position _camera.offset = _final_offset func _notification(what: int) -> void: if not Engine.is_editor_hint(): return match what: NOTIFICATION_PARENTED, NOTIFICATION_UNPARENTED: #print("重設parent") call_deferred("_editor_verify") ## 編輯器層面的通過性驗證 func _editor_verify() -> void: _camera = _find_camera() _editor_valid = _camera != null #print(_editor_valid) if not _editor_valid: _emit_config_warning() else: _warned = false func _ready() -> void: if Engine.is_editor_hint(): return _camera = _find_camera() if not _camera: return _request_register() func _find_camera() -> Camera2D: var p := get_parent() return p as Camera2D if p is Camera2D else null func _request_register() -> void: var sys := Engine.get_singleton(_CONSTANTS.CAMERA_SYSTEM_NAME) if not sys: return _runtime_registered = sys.request_register_pointer(self) func _request_unregister() -> void: if not _runtime_registered: return var sys := Engine.get_singleton(_CONSTANTS.CAMERA_SYSTEM_NAME) if sys: sys.request_unregister_pointer(self) _runtime_registered = false func _emit_config_warning() -> void: if not Engine.is_editor_hint(): return if _warned: return push_warning( "[CameraPointer] Invalid configuration: parent node must be Camera2D. " + "Current parent: %s" % (get_parent() if get_parent() else "null") ) _warned = true func get_camera() -> Camera2D: return _camera