How to make animation play and loop properly upon input

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Dava
:warning: Old Version Published before Godot 3 was released.

I am having a hard time working with gdscript and animation every time i press an input, only the first frame plays and when i release the input, the remaining frames play and it stops on the last frame. Here’s my code

onready var anim = get_node("anim")

func _ready():
  anim.set_speed(2)
  set_process(true)
  set_fixed_process(true)
  pass

func _process(delta):
  if(anim.is_playing()):
      return;
  pass

func _fixed_process(delta):
   var direction = Vector2(0, 0)

   ############### Input #############
   If (Input.is_action_pressed("ui_up")):
       direction += Vector2(0, -1)
       anim.play("walk_back")
       anim.seek(0, true)
  elif (Input.is_action_pressed("ui_down")):
       direction += Vector2(0, 1)
       anim.play("walk_fore")
       anim.seek(0, true)
 elif (Input.is_action_pressed("ui_left")):
       direction += Vector2(-1, 0)
       anim.play("walk_left")
       anim.seek(0, true)
 elif(Input.is_action_pressed("ui_right")):
       direction += Vector2(1, 0)
       anim.play("walk_right")
       anim.seek(0, true)
       pass
 pass
:bust_in_silhouette: Reply From: M. Alkotob

Instead of:

anim.play("walk_fore")
anim.seek(0, true)

Try:

if(not anim.is_playing()):
	anim.play("walk_fore")

This should not be necessary:

anim.seek(0, true)

P.S. Let me know what happens.

Thanks! It worked, but now when i press the walk_down input and then the walk_left input the, walk down animation finishes first before going to the walk_left animation first despite the character actually moving left, same goes for all others

Dava | 2017-03-19 12:36

You need to add another condition to the if() statement.

Is anim of type AnimatedSprite or AnimationPlayer?
Anyway, here is what to change (for both cases):

“AnimationPlayer” →

if(not anim.is_playing() or anim.get_current_animation().basename() != 'walk_down'):
    anim.play("walk_fore")

“AnimatedSprite” →

if(not anim.is_playing() or anim.get_animation().basename() != 'walk_down'):
    anim.play("walk_fore")

Note: ‘walk_down’ is the name of the animation, you should change this for each one.

Let me know what happens :slight_smile:

M. Alkotob | 2017-03-19 14:31

So I tried this instead, because the problem applies to the other animations:

   if (not anim.is_playing() or anim.get_current_animation().basename != 'walk_fore' or anim.get_current_animation().basename != 'walk_back' or anim.get_current_animation().basename != 'walk_left'):
              anim.play("walk_right")

And that turned out to be a disaster, could you give me a more specific idea of what I should do?

I am using AnimationPlayer btw :wink:

Dava | 2017-03-19 17:52

I meant something like this :stuck_out_tongue:

   if (not anim.is_playing() or anim.get_current_animation().basename != 'walk_right'):
              anim.play("walk_right")

M. Alkotob | 2017-03-19 19:34

Huzzah! It now works! The final question: how you make the walk animation stop upon release of input and play the idle animation? The animation keeps playing even though I release input and then it remains on the last frame ,so I tried:

if(Input.action_release("ui_left")):
    anim.play("idle_left")

But that just stops the player from functioning

Dava | 2017-03-20 07:41

Is the direction changed to 0 when he stops moving?

Instead of checking for button release, could check if direction is Vector2(0,0) and play the idle animaition then.

Something like:

if( direction == Vector2(0,0) or or anim.get_current_animation().basename != 'idle_left' ):
    anim.play("idle_left")

To do this for all directions, you’ll need another var to store the direction while walking.
Again, I don’t know how your direction var works in the game code, so you might have to tweak this.

M. Alkotob | 2017-03-20 10:05

Thanks a lot! They all work :slight_smile:

Dava | 2017-03-20 13:06