# res://autoload/scene_transition.gd extends CanvasLayer signal transition_finished @export var fade_duration: float = 0.4 @export var color: Color = Color.BLACK var _rect: ColorRect var _is_transitioning := false func _ready() -> void: # Couche au-dessus de tout layer = 128 # Ne bloque pas les inputs quand invisible process_mode = Node.PROCESS_MODE_ALWAYS _rect = ColorRect.new() _rect.color = color _rect.modulate.a = 0.0 _rect.visible = false _rect.mouse_filter = Control.MOUSE_FILTER_IGNORE _rect.set_anchors_preset(Control.PRESET_FULL_RECT) add_child(_rect) func change_scene(scene: PackedScene, duration: float = -1.0) -> void: var prev := fade_duration if duration > 0.0: fade_duration = duration await change_scene_path(scene.resource_path) fade_duration = prev func change_scene_path(path: String) -> void: if _is_transitioning: return _is_transitioning = true # 1. Fade vers le noir await _fade(1.0) # 2. Changement effectif var err := get_tree().change_scene_to_file(path) if err != OK: push_error("Erreur changement de scène: %s" % err) await _fade(0.0) _is_transitioning = false return # 3. Attendre que la nouvelle scène soit prête await get_tree().process_frame await get_tree().process_frame # 4. Fade depuis le noir await _fade(0.0) _is_transitioning = false transition_finished.emit() func _fade(target_alpha: float) -> void: _rect.visible = true var tween := create_tween() tween.set_ease(Tween.EASE_IN_OUT) tween.set_trans(Tween.TRANS_SINE) tween.tween_property(_rect, "modulate:a", target_alpha, fade_duration) await tween.finished if is_zero_approx(target_alpha): _rect.visible = false