0 votes

I followed a tutorial step by step online and everything works fine, except that when my character executes a jump or fall animation, it only plays the first frame. I'm pretty sure it's because it conflicts with the idle animation. Any help would be extremely appreciated! Here's my code:

extends KinematicBody2D

const UP = Vector2(0,-1)
const GRAVITY = 15
const FALLSPEED = 200
const MAXSPEED = 50
const JUMPFORCE = 300
const ACCEL = 15

var motion = Vector2()
var facing_right = true

func _ready():
    pass # Replace with function body.

func _physics_process(delta):

    motion.y += GRAVITY
    if motion.y > FALLSPEED:
        motion.y = FALLSPEED

    if facing_right == true:
        $Sprite.scale.x = 1
    else:
        $Sprite.scale.x = -1

    motion.x = clamp(motion.x, -MAXSPEED,MAXSPEED)



    if Input.is_action_pressed("ui_right"):
        motion.x += ACCEL
        facing_right = true
        $AnimationPlayer.play("run")
    elif Input.is_action_pressed("ui_left"):
        motion.x -= ACCEL
        facing_right = false
        $AnimationPlayer.play("run")
    else:
        motion.x = lerp(motion.x,0,0.2)
        $AnimationPlayer.play("idle")

    if is_on_floor():
        if Input.is_action_just_pressed("ui_up"):
            motion.y = -JUMPFORCE

    if !is_on_floor():
        if motion.y < 0:
            $AnimationPlayer.play("jump")
        elif motion.y > 0:
            $AnimationPlayer.play("fall")


    motion = move_and_slide(motion, UP)
    if motion.y == 0
        motion.y = 10
in Engine by (12 points)

1 Answer

+1 vote

I think this might be your problem:

if Input.is_action_pressed("ui_right"):
    motion.x += ACCEL
    facing_right = true
    $AnimationPlayer.play("run")
elif Input.is_action_pressed("ui_left"):
    motion.x -= ACCEL
    facing_right = false
    $AnimationPlayer.play("run")
else:
    motion.x = lerp(motion.x,0,0.2)
    $AnimationPlayer.play("idle")

Its the else statement. It states that if your not walking left or right, to play the idle animation. I suggest that within the else statement you write:

else:
    if is_on_floor():
        motion.x = lerp(motion.x,0,0.2)
        $AnimationPlayer.play("idle")

and see if this fixes it. :)

by (372 points)

Thank you so much! Now my character's jump and fall animation plays when I press the right key :) However, if I'm holding the run key while jumping or falling the animation will still only play the first frame.

I really appreciate your help!

However, if I'm holding the run key while jumping or falling the
animation will still only play the first frame

try this.

If Input.is_action_pressed("ui_right") and is_on_floor():
    motion.x +- ACCEl
    etc.

do this for moving left as well, and see if it works. :)

It's probably the run animations also conflicting with it. Try removing all the $AnimationPlayer.play() and add this instead:

if is_on_floor():
    if Input.is_action_pressed("ui_right") or Input.is_action_pressed("ui_left"):
        $AnimationPlayer.play("run")
    else:
        $AnimationPlayer.play("idle")

Millard's solution would also work for getting your animations to play right, but would also take away your horizontal movement control while you're in the air.

what about his jumping and falling animations?

I can't believe I didn't notice the removed movement my code would cause. lol

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.