Top-Down 2D, 4-directional Game: Alternating Footsteps after Leaving Animation

Godot Version

v4.7.stable.official.5b4e0cb0f

Question

Hi,

I am having trouble trying to figure out how I can implement what I want for a character animation.

I realize this is a very stupid thing to want, but I would like to have a character walk and remember which foot they have just stepped with; They can stop walking, and resume walking, but they will lead with the other foot.

I am using an AnimationPlayer node that is utilizing spritesheet data from an Sprite2D node.

All characters (including the player) have 4 facing directions: Up, Down, Left, Right.

Characters (including the player) use a pull state-machine to behave as desired (made by dragonforge-dev [super helpful guy, a lot of my programming of characters has come from reading his stuff!]) Most states have their own set of animations in the AnimationPlayer

(ex. the WalkState, has 4 corresponding tracks in the AnimationPlayer Node: (walkUp, walkDown, walkLeft, walkRight. the same for IdleState, → idleUp, idleDown, idleLeft, idleRight)

Each animation track has 4 animation frames:

  • Frame 0: Left foot (0.0 s)
  • Frame 2: neutral (idle) (0.2 s)
  • Frame 3: Right foot (0.4 s)
  • Frame 4: neutral (idle) (0.6 s)

Now, by default, if the player were to be walking, they would be in the WalkState, the animation would loop, and the feet would be in proper order. However, if the player leaves the state (for example, stops moving, and moves to the IdleState), and comes back to the WalkState, the animation would restart. Tapping the movement keys then would end up with your character always putting the left foot first; which isn’t really how people move naturally.

I would like the character to be able to move, stop, then resume on the other foot.

I’ve tried a lot of stuff, but most of it is hardcoded, and if I ever change how many frames of animation I have, everything gets messed up (it is also just ugly and not scalable at all) [I also realize a solution is to just NOT CHANGE the number of frames, but that feels like a cop-out.]

My original idea was to have two method tracks that can be placed at any frame I would want, right_foot(), left_foot() essentially acting as pieces of meta-data that I could check in the attached script of the AnimationPlayer node. But I just couldn’t get it to work (and unfortunately, I have lost that code, so I really have nothing to show for it!)

I’ve also approached the AnimationTree Node previously, but I don’t really prefer having code tucked away in a node that isn’t an easily accessible script.

I’m new to Godot 4, and whilst I’ve done my best to read through the documentation for the AnimationPlayer Node, no solution has clicked in my head. Is there some easy solution that I’m not seeing/aware of?

Thank you all!

I’m not sure that I’d agree with that (I’m not an expert, either…), but if that’s what you want…
Can you start the walk animation from either the beginning, or from its mid-point, depending on a remembered variable, which alternates at every step..? Something like…

Variable ‘foot’

if foot = true :animation from beginning, and ‘foot’ changed to ‘false’

if foot = false: animation from mid-point, and ‘foot’ changed to ‘true’

Any help..?

what about the methods seek() in AnimationPlayer, and advance() in AnimationMixer, Have you tried them?

you can probably try seeking to either Frame 3, or start at Frame 0, as you said that each animation has 4 frames for each walking animations

seek() in AnimationPlayer is a good idea; I tried to use it along with Call Method Track to see if could get the timestamps of the leftfoot() rightfoot() functions for each animation; but I couldn’t get it to work. I appreciate the help though!

This was what I originally tried to use, but I think either the way Godot’s AnimationPlayer repeats animations, or maybe just something I’m doing wrong based on ticks, makes variables set based on animations from the AnimationPlayer behave weirdly when the animation begins at 0.0s. I would move it up, but this would then make the character slide when the user is tapping a key.

But this feels like this should be the obvious solution, I agree.

Thank you for the help, though!