0 votes

Struggling to get my head round a very simple standard character go left/right script, but im looking to insert a 4 frame 'turning round' animation "Turn" to my 2d character in between moving left or right depending on the direction your looking in.

I know im on the right track, but not close enough!

What have i missed?

Help/pointers appreciated, Ta!

extends KinematicBody2D

var velocity = Vector2()
const speed = 300

func _physics_process(delta):
if Input.is_action_pressed("ui_right"):
    velocity.x = speed
    if $AnimatedSprite.flip_h == true:    < The bit that should work
        $AnimatedSprite.play("Turn", true) < but doest do anything!
    $AnimatedSprite.flip_h = false
    $AnimatedSprite.play("Walk")

elif Input.is_action_pressed("ui_left"):
    velocity.x = -speed
    if $AnimatedSprite.flip_h == false:
        $AnimatedSprite.play("Turn")
    $AnimatedSprite.flip_h = true
    $AnimatedSprite.play("Walk")

else:
    velocity.x = 0
    $AnimatedSprite.play("Blink2")

velocity = move_and_slide(velocity)
asked Jan 13 in Engine by bingbong (19 points)

1 Answer

0 votes
Best answer

In the same frame that you start the Turn animation, it starts the Walk animation, so it does not wait for the Turn animation to end (or even start for that matter). AnimatedSprite.play does not wait for the animation to finish.

To wait for animation completion you could use a yield, but I really don't know if it'll work well in this code, can be a starting point though.

if $AnimatedSprite.flip_h == true:
    $AnimatedSprite.play("Turn", true)
    yield($AnimatedSprite, "animation_finished")

The character will be stuck in place for the duration of the Turn animation.

Edit: Just for future reference, the yield inside a _physics_process is bad, because it's a "stop the world" approach, can cause a lot of bugs. What you'll probably want is something similar to a State machine, in which you go from WALK state into TURNING, and while in the TURNING state you can only leave when $AnimatedSprite.is_playing() == false.

answered Jan 15 by chrs (52 points)
edited Jan 16 by chrs

Thanks so much! Yes that does work, but it is real glitchy, not actually a problem that its stuck in place while its turning (cos it happens in real life!) but the 'Walk' character IS moving, hidden in the background and jumps into existence having moved while the 'Turn' animation is playing stuck in place...

Why doesnt this move the character turning AND the walking bit, its all contained in the same statement!? My head thinks it should work!

We are kind of at the limit of my (simple) coding skills at the moment, so I would appreciate any alternative solutions for this from anyone.

That happens because move_and_slide tries to adjust to the time spent during the animation, you can see in move_and_slide's documentation that it uses the delta time of the _physics_process. The time it spent waiting for the animation to finish will be calculated in the final movement.

To get the behaviour you desire, stop the character while it's turning, you could set the velocity.x to 0 right after that yield, that way there will be no movement.

 move_and_slide() automatically calculates frame-based movement using delta. Do not multiply your velocity vector by delta before passing it to move_and_slide().

Oh man, that works perfectly! Thanks so much!

Oddly, if you tap the key quickly and dont give the turn animation a chance to complete - you can tap it may times - 3 seconds after you stop tapping the key, the character flips the horizontal anyway. (without the turn animation).

Also I chucked a print statement in the lines of code that i was struggling with to see what was happening,

    if $AnimatedSprite.flip_h == true:
        print("F")
        $AnimatedSprite.play("Turn")
        yield($AnimatedSprite, "animation_finished")
        velocity.x = 0

It prints out 5 'F's in the output window when you hit the key to change direction, theres only 3 frames in the turn animation, why would it be cycling through this line 5 times?

Not so important that one, just curious, but the 3 second turn i would like to fix...

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.