Godot Version
4.3
Question
In an AnimationTree, I have an enemy charge attack phase that takes 3 animations. The first startup animation plays when a cooldown timer goes off. When the startup animation finishes, the actual charge attack animation plays, and it is supposed to stop after another timer finishes. Then, it goes to the final animation where the enemy transforms back to normal. My issue is that right when the startup animation ends, it skips the rolling animation entirely and goes to the final “normal transform” animation.
How can I make it so the rolling animation loops and plays for the time specified on the timer before ending?
Here’s the tree:
And here’s the code, the rollTime variable is the timer for how long the rolling animation is supposed to last (2sec):
public override void _Ready()
{
animationTree = GetNode<AnimationTree>("AnimationTree");
stateMachine = animationTree.Get("parameters/playback").Obj as AnimationNodeStateMachinePlayback;
target = GetNode<CharacterBody2D>("/root/Player");
velocity = Velocity;
sprite = GetNode("Sprite2D") as Sprite2D;
dead = false;
health = max_health;
rollTime = GetNode<Timer>("RollTime");
rollCooldown = GetNode<Timer>("RollCooldown");
rollCooldown.Start();
test = false;
}
public override void _PhysicsProcess(double delta)
{
GD.Print(rollTime.TimeLeft);
if (dead == false && hit == false && rolling == false)
{
GlobalPosition += (target.GlobalPosition - GlobalPosition).Normalized() * speed * (float)delta;
stateMachine.Travel("walk");
if (GlobalPosition > target.GlobalPosition)
{
sprite.FlipH = true;
}
else
{
sprite.FlipH = false;
}
}
if (rolling == true)
{
GlobalPosition += Transform.X * speed * (float)delta;
stateMachine.Travel("rolltransform");
}
MoveAndSlide();
}
private void OnHurtAreaAreaEntered(Area2D body)
{
int damage = body.GetNode<playerhitbox>("../AttackArea").damage;
if (body.IsInGroup("Player Attack"))
{
health -= damage;
}
if (health > 0)
{
hit = true;
stateMachine.Travel("hit");
}
else
{
dead = true;
stateMachine.Travel("death");
}
}
private void DropItem()
{
var drop = (Area2D)itemDrop.Instantiate();
drop.GlobalPosition = new Vector2((float)GD.RandRange(Position.X - 15, Position.X + 15), (float)GD.RandRange(Position.Y - 15, Position.Y + 15));
GetParent().AddChild(drop);
}
private void OnCooldownTimeout()
{
rolling = true;
stateMachine.Travel("rolltransform");
}
private void OnRollTimeTimeout() // SIGNAL
{
animationTree.Set("parameters/StateMachine/current", "normaltransform");
stateMachine.Travel("normaltransform");
}
private void StartRollTimer() // CALLED AT THE END OF THE ROLLTRANSFORM ANIMATION
{
rollTime.Start();
}
private void StartCooldown() // STARTS THE COOLDOWN BEFORE THE WHOLE CYCLE IS PLAYED AGAIN
{
rollCooldown.Start();
}