Letting a sprite animation finish

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Ypso

Hi,

In my 2D platformer I want a stopping-animation when my character finishes running. The problem is, it stops playing when I “override” it with new animations like walk and idle.
Is there a way my code can detect which animation is currently playing and also when it finished?

Something like

if current animation name = stopping: wait for animation to finish
else: play idle

Sorry, no actual code, I’m a beginner in this. I’m using animated sprites. Thanks!

:bust_in_silhouette: Reply From: Oen44

Take a look at AnimatedSprite. You can check if given animation is currently playing, you can stop and start or check which frame is actually playing (that can be used to blend animations).
What you can do:
Check for input, if player pressed Right Key, stop idle animation, start walking animation. If player released Right Key, stop walking animation, start idle animation.

#Edit
Click on AnimatedSprite inside scene tree, in properties click on created Frames so it will open Animation Frames interface. Create animations there, name will be used in code (play(animation name) or animation == animation_name). Throw there all frames that are related to given animation and done.

Thanks for your reply.
But how do I use “is_playing” and “animation_finished”?

I tried this:

onready var spritenode= get_node("Sprite")
if spritenode.is_playing():
	print("animation playing")

This works, but where do I put the name of the animation, so I can check if “walk” is the current animation?

if spritenode.animation_finished():
	print("animation finished")

This doesn’t work. I get “Nonexistant function”.

Unfortunately I found the docs not very helpful so far, because there are no examples on how to properly use most things in actual code.

Ypso | 2018-09-18 11:11

If you look at Member Variables you will see:

String animation - The current animation from the frames resource. If this value changes, the frame counter is reset.

I hope you are using AnimationPlayer which is explained in Introduction to the 2D animation features. That way you can check which animation is active (using animation from above) and if it’s currently playing.

Oen44 | 2018-09-18 11:41

Unfortunately I’m using AnimatedSprite right now. Does this mean I have to switch to the AnimationPlayer then? Is this not possible or difficult with AnimatedSprite?

Ypso | 2018-09-19 12:37

That will work too, if you are using AnimatedSprite then SpriteFrames are way to go.

Oen44 | 2018-09-19 12:54

Ok, but how do I use these member functions?

I just want the code in my character (KinematicBody2D) to check, if a certain animation is currently active and if so, do something. Like finishing it before playing the next animation.

Do I use this with func?

func has_animation(walk)
 print("walking")

Nothing happening so far.

Or like this?

func _process(delta):
 if $Sprite.has_animation("walk"):
  print("walking")

Also nothing happening.

Ypso | 2018-09-19 14:02

Check my edit.

Oen44 | 2018-09-19 14:31

Thanks for your effort and all, but we seem to talk past each other, I’ve already created plenty of animations using the AnimatedSprite.
But you kind of helped me :slight_smile:

I’ve now found out, that checking works with this

if $Sprite.animation == "run":
 #do something

The last thing I need is to let the animation finish or check, if it has been finished.
So how do I use “animation_finished()”?

Thanks again.

Ypso | 2018-09-19 15:37

Just use docs that I linked above. It’s all there, you know the amount of frames for each animation so why not check if current frame for given animation is equal to number of frames.

if $Sprite.animation == "run" && $Sprite.frame == $Sprite.frames.get_frame_count("run"):
    # Animation "run" finished

Oen44 | 2018-09-19 15:41

No offence, but as a beginner I find the docs difficult to understand. For me it is mostly “raw data” with no examples how to use it properly.
Your example looks good, but it does not work (at least in my test nothing happened), so I did it like this and it worked, so thank you.

if $Sprite.animation == "run" && $Sprite.frame == 6:
 #Something

Ypso | 2018-09-19 17:00

get_frame_count may return total number of frames. If there is frame 0-5 then get_frame_count will return 6. So try that:

if $Sprite.animation == "run" && $Sprite.frame == $Sprite.frames.get_frame_count("run")-1:
    # Animation "run" finished

It’s easier that way, you don’t have to hardcode numbers or even remember them.
Not tested, just how I think it is.

Oen44 | 2018-09-19 17:06

Well, that worked! Thank you very much!

Ypso | 2018-09-19 17:11