godot-plateformer/addons/reedcamera/scripts/camera_tools/CameraAnchorController.gd

100 lines
2.2 KiB
GDScript3
Raw Normal View History

2026-01-12 17:51:15 +08:00
extends Node
class_name ReedCameraAnchorController
const _CONSTANTS = preload("res://addons/reedcamera/_data/CameraSystemConst.gd")
## =========================
## Private
## =========================
var _anchors: Array[CameraAnchor] = []
var _current_anchor: CameraAnchor
var _current_position := Vector2.ZERO
var _tween: Tween
## =========================
## Config
## =========================
@export var enabled := true
@export var move_duration := 0.4
@export var ease_type := Tween.EASE_OUT
@export var trans_type := Tween.TRANS_CUBIC
## =========================
## Runtime State
## =========================
#var _current_position: Vector2
var _target_position: Vector2
#var _tween: Tween
var _has_target := false
## =========================
## Lifecycle
## =========================
func _ready() -> void:
var sys := Engine.get_singleton(_CONSTANTS.CAMERA_SYSTEM_NAME)
if not sys:
return
_anchors = sys.get_all_anchors()
sys.anchor_registered.connect(_on_anchor_added)
sys.anchor_unregistered.connect(_on_anchor_removed)
_evaluate()
func _on_anchor_added(anchor: CameraAnchor) -> void:
_anchors.append(anchor)
_evaluate()
func _on_anchor_removed(anchor: CameraAnchor) -> void:
_anchors.erase(anchor)
if _current_anchor == anchor:
_current_anchor = null
_evaluate()
func _evaluate() -> void:
var winner := _pick_best_anchor()
if winner == _current_anchor:
return
_switch_to(winner)
func _pick_best_anchor() -> CameraAnchor:
var best: CameraAnchor
var best_p := -INF
for a in _anchors:
if not a.enabled:
continue
if a.priority > best_p:
best = a
best_p = a.priority
return best
func _switch_to(anchor: CameraAnchor) -> void:
if not anchor:
return
_current_anchor = anchor
var target := anchor.global_position
if _tween and _tween.is_running():
_tween.kill()
if not anchor.use_blend or anchor.blend_time <= 0.0:
_current_position = target
return
_tween = get_tree().create_tween()
_tween.set_trans(Tween.TRANS_CUBIC)
_tween.set_ease(Tween.EASE_OUT)
_tween.tween_property(self, "_current_position", target, anchor.blend_time)
## =========================
## CameraPointer Interface
## =========================
func get_base_position() -> Vector2:
return _current_position