0 votes

I'm working on my first game, a plataformer 2d. I want to implement a ledge climb for the Player, so when they detect a ledge, they can climb it. The AnimationPlayer plays the climb_ledge animation, and once it finishes, I move the Player to a specific location (in this case the tile that's up the ledge). This is the specific portion of the code:

CLIMB_LEDGE:
            var target = ledge_climb_pos.get_global_position() 
            animation_player.play("Climb_Ledge")
            yield(get_node("AnimationPlayer"), "animation_finished")
            position = target
            state = WALK

ledgeclimbpos is an Area2d that's a child of the KinematicBody2d set at the specific place where the sprite ends at the end of the animation: https://ibb.co/qsfFvVb

frames

AnimationPlayer.play("Climb_Ledge)

("reference frame" is not part of the animation, is just to illustrate where the Player should end up) After yield, I set the position of the Player to that target location. It works, but there is an extra frame of the animation that appears for a fraction of a second, as if the next animation (in this case an Idle) started playing at the target's previous location before setting the new location.
Here's a video that illustrates what I mean: https://youtu.be/_eRdaubooVo

I hope this is clear. English is not my first language.

Thanks in advance!

in Engine by (25 points)
edited by

2 Answers

0 votes
Best answer

Ok! So I think I figured it out. AnimationPlayer has a void method called advance. This is the description in the documentation:

void advance ( float delta )
Shifts position in the animation timeline and immediately updates the animation. delta is the time in seconds to shift. Events between the current frame and delta are handled.

To be honest, I don't fully understand how or why this works, but I changed the code to:

CLIMB_LEDGE:
    var target = ledge_climb_pos.get_global_position()                      
    animation_player.play("Climb_Ledge")                  
    yield(animation_player, "animation_finished")   
    animation_player.advance(delta)     #THIS IS THE ADDED LINE       
    position = target  
    state = WALK

... and now the position seems to be updated correctly, in between the last frame of the "Climb_Ledge" animation and the first of the "Idle" animation. I then just had to turn the Smoothing property of the Camera2D to "Enabled" so the camera doesn't jump between the old and new positions, and this is how it looks: https://youtu.be/SsgSHFhdNyY

Hope this is helpful to someone else :) Thanks!

by (25 points)
0 votes

On a closer inspection, there is no extra frame being played. What happens is that the Animation Player gets to the last frame of the animation (the third one on the image I shared), then the position is reseted while the frame is still visible, and then the next animation begins playing. Still don't know how to solve it, though

by (25 points)
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.