100 lines
2.2 KiB
GDScript
100 lines
2.2 KiB
GDScript
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
|