Animation Player setup in Player scene doesn't play animations in a new scene that is a cutscene.

Godot Version

Godot 4.4

Question

I have a character_creator.tscn where you can select body, outfit, hair, and color and it successfully loads to the Player. In my “player.tscn” I setup an Animation Player with an Animation Tree that correctly follows the direction that the player faces. That Animation Player also animates correctly, regardless which body, outfit, hair, and color was selected.
When I create a New Scene and instantiate the Player as a child scene, everything works perfectly.
My “main.tscn” works great.

My problem is that I created New Scene, “intro1.tscn” that has it’s own Animation Player to control the cutscene, but the Player walk animations do not play until after the animation is complete.
I am key framing the transform position in the new Animation Player in this scene. The player just slides to the position, the animations do not play. However, once the animation time is over, I can control the Player and the Player animations work perfectly again. - they are just not playing when the 2nd Animation Player is playing.

I tried to @export direction_vector and @export input_vector but changing those in keyframes did not affect the direction of the player while the “intro 1 cutscene” plays.

What is the best way to have the Player’s Animation Player work properly in a different scene that has it’s own Animation Player?

You could try controlling your player animations in the cutscene animation player by adding a Property Track. This will allow you to keyframe export variables on your player script (such as your current player state, if you use a state machine to handle your animations).

1 Like

Thank you for your reply! I do use a state machine for my animations, I have it in an animation tree but when I add Property Track, and click on the Player, I don’t have access to the animation tree that switches between the idle and walk state.
How do I get access to the Player’s animation tree as a Property Track of the animation player in the 2nd scene?

I don’t think an animation player can control another animation tree like that.

Instead of accessing the player animation tree, access the State Machine via Property Track and use the cutscene animation player to switch your player’s state, which should then trigger the walking animation.

Depends on how your state machine is set up, but I’ll give a brief example:
Let’s say you store your player state in @export var current_state. Because the variable is exported, it should show up in the Property Track when you access your player node. From there, you could switch it from “idle” to “walking”, which then should trigger your animation.

Thank you again! I followed a tutorial to setup my state machine and had to refactor the blend trees just now in order to make them viewable in my inspector. I re-did my transitions and have everything working when I play the game.
To debug I have print(state) and print(input_vector) and godot is recognizing the state and input_vector properly in the game.
I can tell I’m getting closer, but the player animations still do not work in my “intro_one.tscn” unless I am actively pressing one of the input buttons. Even if I key frame the state to be “WalkState” in my inspector, my debug doesn’t see it unless I press an input button.
I “@export var state” but then the issue is, how do I connect that to the actual state that is calculated during my _physics_process?
I tried @export var state = “WalkState” and that works in game, plus the debugging shows the correct input_vector and correct state in game, but the keyframes do not change the behavior in the Animation.
I tried “@export var current_state = state” (state is what I call it in the _physics_process function) but that doesn’t work because state is defined out of scope.
I feel like the solution is right in front of my face, but I am still a pretty novice game developer and nothing that I try is working.
I added an "if state == “WalkState” and “elif state == “IdleState”” in my player code and that also works properly. I can not figure out how to connect the variable from the _physics_process to be seen as an @export so that I can control the keyframe in the Animation Player.

Do you have any other suggestions?

Thank you again!

I played around a little and might have found a solution.

It seems that as long as the movement logic is within the physics_process, it will always override the animation players key frames, because it’s always listening for an input instead.

So, in the script I added a variable that acts as a switch, I just called it “@export var controlled = false”.

In the physics_process, I simply say:

if !controlled:

	[put your normal movement/state machine code here]

else:
	return

So, as long as the controlled boolean is false, the entire moving logic will be ignored.

Then, I moved my animation handling to the regular _process function instead:

if current_state == STATE.Walking:
	animation_tree.set("parameters/Transition/transition_request","Walking")
elif current_state == STATE.Standing:
	animation_tree.set("parameters/Transition/transition_request","Standing")

Now, with everything set up, you can access those values via animation player normally just by clicking on the node (no Property Track needed).

I did test this with a Companion NPC, not the Player, but the state machine and animation handling is the same, so it should work for you.

Thank you so much! The “controlled” boolean works and is controlled by keyframes in the Animation Player exactly as described.
However, I still can not get the global “state” to impact the Animation Controller. No matter what I set for the “state” in the Inspector, it always starts as “IdleState.”
I think I found part of the issue.
Looking over everything, I think this has to due with how my input is setup. The input_vector is what controls the Animation Player’s BlendTree2d transition between IdleState and WalkState, so without an input_vector, I am stuck in Idle, no matter what I set as a keyframe.
It’s possible the way I am currently monitoring the active node of the BlendTree is causing this issue. I got this from the same tutorial where I first setup my player movement and state machine.

@onready var playback = animation_tree.get(“parameters/StateMachine/playback”) as AnimationNodeStateMachinePlayback

Then, in the func _physics_process() I had

var state = playback.get_current_node()"

but I created a func _process() and moved it there, with the rest of the state/animation handling.

So, I’m thinking the problem is that no matter what I put in the keyframe, this line of code over rules that. The issue is, that line of code is how my state machine knows which state it’s in and I do not know any other method to monitor which state the game is in.

As mentioned earlier, I am pretty novice, although I do have some experience with Unity as well and am aware that there are many ways to setup player inputs and character animations.
Do you think I will be able to connect my system to the AnimationPlayer or is the input_vector and/or func _physics_process() overly complicating things?

My game is very simple. It is a 2d top down adventure style, educational game; there is no attacking or special moves, just idle, walk, and sprint plus some interactions with NPCS and objects (I’ve got my dialogue system working).

Thank you again for all your time! When I finish, I will be sure to give you a shout out in the credits!

maybe try having the player.player ani, in its own scene and run it separate than attaching it to the rest ?

It’s either the way you handle the input, or how you have set the AnimationTree up. You are using AnimationNodeStateMachine, but I am using AnimationNodeBlendTree - maybe part of the issue lies there.