extends Node class_name ContainerTween signal finished enum AnimateOrder { AS_IS, TOP_TO_BOTTOM, BOTTOM_TO_TOP, LEFT_TO_RIGHT, RIGHT_TO_LEFT } @export_group("Settings") @export var targets: Array[Control] @export var runtime_target_parent: Control @export var tween_types: Array[String] = ["punch_in"] @export var order: AnimateOrder = AnimateOrder.AS_IS @export var stagger_delay: float = 0.05 @export var show_on_start: bool = false @export var hide_on_finish: bool = false @export var reset_state_on_start: bool = true var _tween_generation: int = 0 var is_running: bool = false func start_tween() -> void: if is_running: return is_running = true _tween_generation += 1 var current_gen = _tween_generation var sorted_targets = targets.duplicate() if !targets.is_empty() else runtime_target_parent.get_children().duplicate() match order: AnimateOrder.TOP_TO_BOTTOM: sorted_targets.sort_custom(func(a, b): return a.global_position.y < b.global_position.y) AnimateOrder.BOTTOM_TO_TOP: sorted_targets.sort_custom(func(a, b): return a.global_position.y > b.global_position.y) AnimateOrder.LEFT_TO_RIGHT: sorted_targets.sort_custom(func(a, b): return a.global_position.x < b.global_position.x) AnimateOrder.RIGHT_TO_LEFT: sorted_targets.sort_custom(func(a, b): return a.global_position.x > b.global_position.x) var last_tween: Tween = null for target in sorted_targets: if current_gen != _tween_generation: return if is_instance_valid(target): if reset_state_on_start: target.scale = Vector2.ONE target.modulate.a = 1.0 if show_on_start: target.show() for type in tween_types: var tween = TweenFX.call(type, target) if tween is Tween: last_tween = tween if hide_on_finish and tween is Tween: tween.tween_callback(target.hide) if stagger_delay > 0.0: await get_tree().create_timer(stagger_delay).timeout if is_instance_valid(last_tween) and last_tween.is_running(): await last_tween.finished if current_gen == _tween_generation: is_running = false finished.emit() func stop_tween() -> void: is_running = false _tween_generation += 1 var current_targets = targets if !targets.is_empty() else runtime_target_parent.get_children() for target in current_targets: if is_instance_valid(target): TweenFX.stop_all(target)