godot-plateformer/addons/reedcamera/scripts/CameraPointer.gd

126 lines
2.5 KiB
GDScript3
Raw Normal View History

2026-01-12 17:51:15 +08:00
@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