Scene transition animation works only first time

Godot Version

4.3

Question

I have a main_title from where player can go to play screen by clicking a button. And I made it with transition like that:

@onready var SceneTransitionPanel : Node2D = %SceneTransition
@onready var SceneTransitionPlayer : AnimationPlayer = %SceneTransition/AnimationPlayer

func _on_start_button_pressed():
	SceneTransitionPlayer.play("fade_out")
	await SceneTransition.animation_finished
	get_tree().change_scene_to_file(<path_to_scene>)

SceneTransition is an AnimationPlayer from included scene, and it has fade_out animation.
After scene is changed, game_screen plays fade_out transition:

@onready var SceneTransitionPanel : Node2D = %SceneTransition
@onready var SceneTransitionPlayer : AnimationPlayer = %SceneTransition/AnimationPlayer

func _ready():
	SceneTransitionPanel.visible = true
	SceneTransitionPlayer.play("fade_in")
	await SceneTransition.animation_finished
	SceneTransitionPanel.visible = false

SceneTransitionPanel is a separate Node2D scene with ColorRect and AnimationPlayer nodes. With AnimationPlayer configured like this:

In both scenes SceneTransitionPlayer is a local variable.
Everything is working, but only for the first time.
When I go back to main_title scene, and press play button, nothing is happening, and no error is given. It looks like the animation is stuck on the first frame. If I only leave get_tree().change_scene_to_file(<path_to_scene>), there is no problem. But the transition is absent. And I want it.

What more can I provide for you people to understand, what am I doing wrong?

How are SceneTransitionPanel and Player defined?

Updated my original post. Hope it gives more clarity.

Could you also show your scene tree for both scenes? This seems like a missused unique name or missused global. Unique node names can only be used in very specific scenarios, they are not for finding genuinely unique nodes, more for shortening long node paths; the scene must have the unique node as a child to access it. if instantiated the parent cannot access the same unique name.

Are you using any Global scenes or scripts? Maybe that would be a better place for your scene transition panel? Do you have any errors?

Now I made a global LoadManager script, where I instantiate this scene with code

func start_load() -> void:
	var state = ResourceLoader.load_threaded_request(_scene_path, "", user_sub_threads)
	if state == OK:
		set_process(true)


func load_with_transition(scene_path: String) -> void:
	_scene_path = scene_path
	
	var new_transition_screen = _trans_screen.instantiate()
	get_tree().get_root().add_child(new_transition_screen)
	var animationPlayer = new_transition_screen.get_node("AnimationPlayer")
	animationPlayer.play("fade_out")
	
	await animationPlayer.animation_finished
	new_transition_screen.queue_free()
	start_load()

Nothing better. First time - plays perfectly, second time - stuck on first frame. Maybe after playing animation, they should be reset somehow?

No errors? The animation player should be destroyed if you are calling change_scene_to_file, and you are making a new one by instantiating _trans_screen. How is your scene tree layed out?

Here is a screenshot of my TitleScreen scene layout, and SceneTransition layout. Since I am new user, I can only post one image.

I don’t think, it will help, actually…

If your game scene has a camera then SceneTransition will be placed in a strange spot, I would highly recommend changing the SceneTransition’s type to a CanvasLayer so it’s children will be affixed to the camera

So, apparently, something is wrong with the scene I am changing to. Played a transition on another scene, went back to title, everything works as expected. Now redoing that scene, an if I will get, what was wrong, I will post here.

It appears, that my pause menu functionality messed things up. When I show pause menu, I set Engine.time_scale = 0, and I didn’t set it to 1 when I quit to main menu.

1 Like

Node.request_ready()
check this method

when something works for one time… Culprit is almost the same.