Godot Version
v4.3.stable.mono.official [77dcf97d8]
Question
I have a really odd behaviour with my AnimationPlayer that I honestly never ran into before. I have a few very basic animations that animate a Sprite2D’s Frames, as well as change it’s Texture, HFrames and VFrames at the very first keyframe when changing from one animation to the other.
This works great, and has worked for me for a long time before, but today I ran into an issue I never discovered before just when I started to rework how my AI moves, so I wanted to start simple and just rework it’s basic animation states. Here’s the code I have for it so far:
using System;
using Godot;
namespace GameName.Scripts.Entities.AI;
public partial class AiAnimationController : AnimationPlayer
{
[Export] private GameCharacterEntity _character;
public override void _Process(double delta)
{
base._Process(delta);
Action transitionAction = GetTransitionAction();
transitionAction?.Invoke();
}
private void PlayIfNotPlaying(string animationName)
{
if (CurrentAnimation != animationName)
{
Play(animationName);
}
}
private Action GetTransitionAction()
{
return CurrentAnimation switch
{
"Idle" when Math.Abs(_character.Velocity.X) > 0 =>
() => PlayIfNotPlaying("Walk"),
"Walk" when Math.Abs(_character.Velocity.X) == 0 =>
() => PlayIfNotPlaying("Idle"),
("Walk" or "Idle") when !_character.IsOnFloor() && _character.Velocity.Y < 0 =>
() => PlayIfNotPlaying("Jump"),
("Walk" or "Idle") when !_character.IsOnFloor() && _character.Velocity.Y > 0 =>
() => PlayIfNotPlaying("FallLoop"),
"Jump" when !_character.IsOnFloor() && _character.Velocity.Y >= 0 =>
() => PlayIfNotPlaying("FallInit"),
"FallInit" when Math.Abs(CurrentAnimationLength - CurrentAnimationPosition) < 0.2 =>
() => PlayIfNotPlaying("FallLoop"),
("FallInit" or "FallLoop" or "Jump") when _character.IsOnFloor() =>
() => PlayIfNotPlaying("Idle"),
_ => () => { }
};
}
}
What I noticed is that this works great, up until I play an animation that was non-looping, such as the jump animation. As soon as that happens, no matter how I call the Play()
method afterwards, no other animations will ever play, and it’ll be stuck on the last frame of the animation that wasn’t set to loop.
Is this intended behaviour or am I missing something?