Can't stop animation from playing

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

I am having a struggle with how to properly stop my “run” animation from playing when there is no input.

Here is my code for in-game character control:

extends KinematicBody2D

onready var animSpriteNode = $AnimatedSprite
var speed = 150
var move = Vector2()

func _ready():
	position = Vector2(get_viewport().size.x/2, get_viewport().size.y/2)

func _physics_process(delta: float):
	if Input.is_action_pressed("up"):
		animSpriteNode.play("run")
		position.y -= 1
	if Input.is_action_pressed("down"):
		animSpriteNode.play("run")
		position.y += 1
	if Input.is_action_pressed("left"):
		animSpriteNode.flip_h = true
		animSpriteNode.play("run")
		position.x -= 1
	if Input.is_action_pressed("right"):
		animSpriteNode.flip_h = false
		animSpriteNode.play("run")
		position.x += 1
	move_and_slide(move*speed)
:bust_in_silhouette: Reply From: jgodfrey

By the looks of your code, I assume your run animation is set to looping? That is, I assume once you start it is just runs constantly. Otherwise, it should stop when it gets to the end (and be restarted by some other movement keypress).

If you set the animation to not loop (an icon at the right end of the animation player timeline), I think the problem will go away.

Alternatively, if you intend to have a looping animation, you’ll need to forcibly stop it when no keys are being pressed. One way to do that (based on your above code) would be:

func _physics_process(delta: float):
    if Input.is_action_pressed("up"):
        animSpriteNode.play("run")
        position.y -= 1
    elif Input.is_action_pressed("down"):
        animSpriteNode.play("run")
        position.y += 1
    elif Input.is_action_pressed("left"):
        animSpriteNode.flip_h = true
        animSpriteNode.play("run")
        position.x -= 1
    elif Input.is_action_pressed("right"):
        animSpriteNode.flip_h = false
        animSpriteNode.play("run")
        position.x += 1
    else animSpriteNode.stop()

    move_and_slide(move*speed)

Though, note, that’ll prevent you from getting input from multiple keys in the same physics frame. Not sure if that’s ok here or not. If not, you could do something like this instead:

func _physics_process(delta: float):
    var running = false
    if Input.is_action_pressed("up"):
        animSpriteNode.play("run")
        position.y -= 1
        running = true
    if Input.is_action_pressed("down"):
        animSpriteNode.play("run")
        position.y += 1
        running = true
    if Input.is_action_pressed("left"):
        animSpriteNode.flip_h = true
        animSpriteNode.play("run")
        position.x -= 1
       running = true
    if Input.is_action_pressed("right"):
        animSpriteNode.flip_h = false
        animSpriteNode.play("run")
        position.x += 1
        running = true

    if !running:
        animSpriteNode.stop()

    move_and_slide(move*speed)

Thanks for your explanation. Yes, you are right, my animation was set to loop, but, frankly speaking, according to my recent research, I see that my way of implementation of character control is very simple and pretty awful). I am gonna try to learn the better ways of doing it. Thanks again for your response!

tokechu | 2020-04-17 19:23

I am doing an shoot animation, i did this and the animation is not playing
func _physics_process(delta):

if Input.is_action_pressed("tiro"):
	animate.play("Shoot")
else:
	animate.stop()