Animation Tree Question?

Godot Version

Godot: 4.2.2

Question

Animation Tree

Hello all,

This is a hard question to ask. So I’ll start at the beginning. When I started learning about Godot all the animations used in the tutorials where created using Animated sprites. Was an easy way to do it but you manually had to tell Godot when to switch animations and got very messy very quickly. Then I did a course were the animation were “controlled” by the Animation Tree. The animations were created in the player and the Animations were controlled by the tree. The thing is that the way the animation were controlled in the Tree was not really explained, yes, through trial and error I have been able to add some things that I wanted but there are other things that I want to add and have no idea where to start.

For this project I want to add ladder climbing to the project. I say add, but, the ladder climbing is implemented, it’s just not being controlled by the Animation tree - just to make sure I had a clear idea of where I was going. I made animated sprites and used the manual control to make the sprite states visible and change from “idle” to movement states on the ladder. I also plan to add wall-climbing wall-jumping behaviours later. Saving the hardest part till last.

Now the plan is to add the ladder climbing to the Animation Tree, but, as I said I have no idea how. You can jump to the ladder as well as just climbing just to make it a little more difficult.

Currently I have three animation trees from the “root” for the non-weapon state. I really don’t understand how they work together and wasn’t really explained in the course - I really needed more experience with Godot before jumping into this course. I had the same problem with the animation controller in an Unreal course they were given to us without explaining how it “REALLY” works. So I don’t get where I need to add the ladder climbing, I do have a basic understanding of the switching and the expression used in the Animation Tree, but that is it.

These are in order (see piccies):

Root: following “Without Sword”

  1. Without Sword

  2. Movement

  3. Locomotion

So, I need help as to how to go about adding the ladder climbing and how to handle the jumping to the ladder without coding the sprites manually. For instance I don’t know whether i need to add the state to the existing framework somehow or whether I need to add another branch to the tree. And if I add a new branch to the tree, how, I would hook it up the existing framework to get it all working.

The code currently controlling this part of the project as of today far is this:

if(! is_on_floor() && on_ladder):
		#this works
		#print("Ladder up!!!");	
		
		#turn off jolly roger completely when on ladder
		#and turn on ladder_anim
		sprite_2d.visible = false;	#works
		ladder_anim.visible = true;	#works
		
		#if (velocity.x != 0):
			#print("Stop moving");
			#velocity.x=0;
		if(Input.is_action_pressed("run_left")):
			print("Roger wants to move left");
			ladder_anim.play("ladder_climb");
			velocity.x = -2;
		elif(Input.is_action_pressed("run_right")):
			print("Rightio");
			ladder_anim.play("ladder_climb");
			velocity.x = 4;
		else:
			velocity.x = 0;
		
		if(Input.is_action_pressed("Up")):
			print("Roger wants to move up");
			ladder_anim.play("ladder_climb");
			velocity.y = -90;
		elif(Input.is_action_pressed("Dash")):
			print("roger wants to move Down");
			ladder_anim.play("ladder_climb");
			velocity.y = 90;
		else:
			stop_jump();
			print("Idling on the ladder");
			velocity.y = 0;
			#stop_jump();
		#end inner if
	#end if
	#--  end ladder code  ------------------------------------------------------

I know that was hard slog getting through the question. But I want to be thorough with what I have done and what I need to do. So if you have any advice on how to proceed any assistance would be gratefully accepted.

Warmest Regards.

Hmm I’ve never used animation tree, I use animation player in combination with a sprite sheet for all my 2D animations.

Is there a specific advantage AnimationTree has for you that you can’t do with AnimationPlayer?

With AnimationPlayer you shouldn’t have to set certain ones visible. You would just play whichever animation you need to for the situation. You can use it in conjunction with a basic StateMachine set-up, or if you need it and have a lot of different states then maybe set-up a more advanced FSM(finite state machine). It seems you are using AnimationTree sort of as a psuedo StateMachine, but just for animations. It may be more advantageous if you have a lot of unique states to look into State Machines, which would allow you to adaptively change animations as well as control player actions in each state.

I had a project that did not use an animation Tree and I had a terrible time getting the correct animation to play, I needed help here on this forum to get it working correctly whereas with the tree the correct animation always plays. But the course it was in didn’t explain how the correctly use the animation tree it was designed for slightly more advanced students than me. I had the same problem in Unreal where you are dealing with upwards of 30 3D animations, they play the correct animation through a tree-like structure . Again in the Unreal course they did not fully explain “HOW” the tree works.

I think there are some real specific advantages to using a Tree in that it is more professional and easier to work with in the long run especially when using the switch mode and expressions to control the animation. Like if you are:

!on_the_floor() (in the air)

or

velocity.y < 0 (usually jumping up)

Or, combinations of things like

!on_the_floor() && velocity.y >= 0 (falling)

with a branch of that so that if you are falling and you hit the dash button then the dash animation will play. You don’t need to set the falling sprite after that on what happens when you land because that is already catered for, I don’t know how on earth I would code that with just the animated sprites. And the tree uses State Machines, nothing pseudo about it, I just don’t understand how?!?

The correct animation will be picked out and play no matter what else is going on in the game, it is a level of abstraction that is necessary in a game particularly in 3D, but, the principal is also good for 2D.

Imagine trying to get the animation in a 3D, 3rd person game, to play a crouch movement with the legs while using the aiming. I have no idea if that would be even possible.

But I am a novice and even worse when it comes the animation tree. Hence the question. The code you are seeing was just to make sure that the animations worked, I have both these animations ready in the Animation player ready to be plugged into the tree once I figure out how. I don’t know how to play an animation in the Animation Player without using the Animation tree, it’s not something I have learnt or even vaguely come across.

Click on the arrow, find the expression in the properties panel, switch to the new state when the expression result is true

The animation tree can only help you switch animations, and you should write a script to move them

Pardon, saying psuedo statemachine is probably inaccurate, my understanding it is a statemachine for handling only the animation side of things.

I’ve never used the animation tree, or animatedsprites, I only use animationplayer.

I was suggesting if your character has multiple actions already, to create a state machine for controlling your characters actions, then inside those states you would call the actions.

Example,

States : Falling, Dashing and Idle

In your falling State you’d set animation to falling.

While falling you dash, dashing state sets animation to fall_dash because it knows the previous state was falling.

You land the state changes to idle since you are no longer falling, and you arent dashing.

You dash, your dashing state knows your previous state was idle so it plays the ground_dash animation.

Playing animations in the animationplayer is as simple as just calling the play function with which animation you want to play.

$AnimationPlayer.play(“dash”)

You wouldn’t have a sprite at all with animation player, in 2D you could just make a sprite sheet with all your animations and change the sprite sheet coords depending on animation. The animationplayer gives your character their texture.

Interesting! That’s almost the same method as using the animated sprite, it’s a wonder I never came across that method before.

Let’s say for the sake of the argument that I was interested in pursuing this method of setting these so called states outside of the Animation Tree how would I go about setting this up.

For instance without the sword I have these animations:
idle
ground
Run
Jump
Fall
then
Run → jump->Fall->Dash
Run-> Jump->Dash-> Fall
Hit animation
Dead animation

Then all those again with the sword plus:
Hit w/ Sword
Ground attack 1
Ground attack 2
Ground attack 3
Jump → air attack 1
Jump->Air attack 2
Jump-> w/ sword
Fall w/ sword
Ground sword
Idle w/ sword
Run w/ Sword

Ladder Climb
Jump->Ladder idle->ladder climb->move off ladder fall
Jump->idle Wall climb->wall climb jump

With maybe a few other to come later, providing I can get the Wall Jumping working at all. Like I have the character swinging on a rope would be nice to have an animation for that and jumping off a well. Drawing and sword and noto would be nice as well.

So, how would I go about making all those transitions work with the state machine you are describing, because I have no idea?

Yeah for sure. State Machines can get a bit complicated at first when you are setting them up, but it can help immensely when handling multiple different actions.

So, one way is to create a node structure with Nodes. The first would be the StateController this would handle transitioning to different states and handling all that.

You would then have Unique states as children of this node.

Idle, on_ground (I don’t understand difference between this and idle), run, jump, fall, hit, dead, attack.

Within each of these states you would handle the logic for that action. You could easily add a variable has_sword, which would let each action know which animation to play. You would also have variable in your StateController previous_state, this woild then be used by each state to know if it is a chained action, thus if there is a unique action to play.

For attack if previous_state == ground: do ground attacks.

For jump if previous_state == run: play run_jump animation.

So each state would handle all of the checks for which animation/action to do. Maybe tonight if I have time I can mock up a basic state machine as an example.

You could create a state for ladder, or you could just depending on what you need create a var on_ladder then in your move and idle states control ladder interaction. It really is more of a structure design issue.

So each state would know which states it can move to, and the parameters to move to a new state. Example, Idle can move to jump, run, hit, dead or attack if has_sword. So, you would put the checks for changing to the next state in idle.

If button pressed is jump → transition → statecontroller → transition to jump.

So, you’d just create the minimal needed parameters for transitioning to the next state. All states can’t transition to every other. Example (unless you have disappearing floors) idle can’t transition to falling.

With state machines you need to make sure your loop is connected so that every state path can lead back to idle or game over.

Example:
Idle → run → jump → fall → ground → idle

Bad Example:
Idle → run → jump … (jump state has no way to transfer to idle or run after landing)

Think of it this way, when you are idle what can your character do, these are the states it can transition to.

When you are jumping/finished jumping what can your character do, these are the states you transition to.

1 Like

Here is a very basic example of a state machine, they can be better formulated, but I just wanted to throw out a visual idea to help you think through what I am saying.

State Parent Node

extends Node

#State parent

enum {IDLE,RUN,JUMP}

var current_state := IDLE
var previous_state := IDLE
var player : Node2D

@onready var StateDict := {IDLE:$Idle,RUN:$Run,JUMP:$Jump}

func set_up() -> void:
	for state in StateDict:
		StateDict[state].player = player
		StateDict[state].state = self

func _process(_delta: float) -> void:
	StateDict[current_state].update_process()

func _physics_process(_delta: float) -> void:
	StateDict[current_state].update_physics()

func change_state(new_state) -> void:
	previous_state = current_state
	current_state = new_state
	StateDict[current_state].previous_state = previous_state

State Idle Node

extends Node

enum {IDLE,RUN,JUMP}

var previous_state := IDLE
var player : Node2D
var state : Node

func update_process() -> void:
	pass

func update_physics() -> void:
	if Input.is_action_just_pressed("north"):
		state.change_state(JUMP)
		print("JUMP!")
	if Input.is_action_just_pressed("east"):
		state.change_state(RUN)
		print("RUN!")

State Run Node

extends Node

enum {IDLE,RUN,JUMP}

var previous_state := IDLE
var player : Node2D
var state : Node

func update_process() -> void:
	pass

func update_physics() -> void:
	if Input.is_action_just_pressed("north"):
		state.change_state(JUMP)
	if Input.is_action_just_pressed("west"):
		state.change_state(IDLE)
		print("IDLE!")

State Jump Node

extends Node

enum {IDLE,RUN,JUMP}

var previous_state := IDLE
var player : Node2D
var state : Node

func update_process() -> void:
	pass

func update_physics() -> void:
	if previous_state == RUN:
		print("RUN and JUMP!")
	else:
		print("JUMP!")
	if Input.is_action_just_pressed("south"):
		state.change_state(IDLE)
		print("IDLE!")

“Character” Node for test

extends Node2D

func _ready() -> void:
	$State.player = self
	$State.set_up()
1 Like

Thankyou that is what I was after an example of how one would work - going to take some time to digest this. I will certainly try this in my next project unfortunately in this project I have gotten in too deep with the animation tree and need to figure out how this works as I have both hero and enemy animations all reliant on the Animation tree.

I really think your way may be easier - a lot, lot easier - in the long run.

Thanks so much for your time and patience.

Beir bua agus beannacht!

No worries, sorry that I’m not well versed in the AnimationTree. StateMachines are super useful for action transition and logic, especially as they get more complicated.