+1 vote

Hi, I'm totally new to coding and making games. I'm working on a skateboard game in 2d.

I am using the Animated Sprite. I need a way to have an idle animation that plays, and then use inputs to trigger trick animations. The trick animations need to hide when they reach the final frame, and reset to frame 0 so that they play from the beginning when they're called next.

I am trying to do something like this, but I am getting an error message that my last line of code is using an unexpected assign. That's confusing because I am using the same command a few lines above, and that instance has no errors:

if Input.is_action_pressed("ui_Kickflip"):
    $Rolling.hide()
    $Kickflip.frame = 0
    $Kickflip.show()
    $Kickflip.playing = true
if $Kickflip.frame = 26
    $Kickflip.hide()
    $Rolling.show()
in Engine by (29 points)

3 Answers

+4 votes
Best answer

When using AnimatedSprite node you're supposed to store your animations in one node and use AnimatedSprite.play("animationName") method (https://docs.godotengine.org/en/3.0/classes/class_animatedsprite.html#class-animatedsprite-play)
If you do that you don't have to bother about hiding/showing nodes and you can also use animation_finished() event to restart your idle animation (which should be on loop unlike trick animations). Though you may want to add one extra frame to your trick animations because event triggers as soon as animation gets to the last frame so if you change it right away you may not be able to see it.
Overall it should be something like this:

func _process(delta):
    if Input.is_action_pressed("ui_Kickflip"):
        $AnimatedSprite.play('Kickflip')
    elif Input.is_action_pressed("ui_OtherTrick"):
        $AnimatedSprite.play('OtherTrick')
    #elif ...

func _on_AnimatedSprite_animation_finished():
    if $AnimatedSprite.animation != 'Rolling':
        $AnimatedSprite.play('Rolling')

I suggest also to choose your idle animation in editor and check "playing" so it will start with idle animation right away.

by (145 points)
selected by

Thanks G, much appreciate the tips.

func _on_AnimatedSprite_animation_finished():
if $AnimatedSprite.animation != 'Rolling':
    $AnimatedSprite.play('Rolling')

What is the exclamation mark doing? Is that saying "If the animation isn't 'Rolling'?"

Also, if there is any kind of introduction to script that you recommend, I would appreciate your insight.

Exactly. "Not equal". Overall function means "When some animation is finished check if it is not idle animation that finished then start idle animation".
As a reference you can use this:
http://docs.godotengine.org/en/3.0/getting_started/step_by_step/your_first_game.html
It explains step by step how to use AnimatedSprite for animation along with some other stuff.
First you create, name and fill your animations inside AnimatedSprite. Then in your script you define under what circumstances you change your animation and to which one. And then you connect AnimatedSprite signal animation_finished to your script so that you can restart your idle animation after trick is finished or maybe choose to restart trick animation (or don't replace it with idle it if its looped by default) if you're still in progress of performing your trick.
You may also consider using this instead for your animation:
https://docs.godotengine.org/en/3.0/tutorials/animation/introduction_2d.html
its more flexible, but may be harder to start with.

0 votes

Figured it out, but I have no idea if this is a reasonable or efficient solution? I'm planning on having about 32 tricks in the demo version. I set the node to send a signal when the animation finishes, and I used a function to hide the trick animation and play my idle animation.

Using $Node.frame = 0 resets the animated sprite to the first frame. If you're using a looping animation you don't have to worry about it. But if you want to call an animation and have it play once, then you have to tell Godot to play that animation from Frame 0, otherwise it will just recall sprite with the last frame cued up.

if Input.is_action_pressed("ui_Kickflip"):
    $Rolling.hide()
    $Kickflip.frame = 0
    $Kickflip.show()
    $Kickflip.playing = true

func _on_Kickflip_animation_finished():
$Kickflip.hide()
$Rolling.show()
by (29 points)

That frame = 0 part was what sent me googling, thanks for that.

I am still used to gotoAndStop() and gotoAndPlay() from the good old ActionScript days and was wondering why an animation wouldn't play (after the first successful playing) even when told to.
This manual resetting feels a bit awkward, but as long as it works... ;)

+1 vote

I know this question is two years old and it doesn't matter anymore, but I don't usually know the answers to questions. Your unexpected assign is in your second if statement: "if $Kickflip.frame = 26" should be "if $Kickflip.frame == 26:".

You're missing a second equal sign and the colon at the end of the statement. The error is being called by the first issue, but the second will also call an error once you fix the first. When using comparison, you have to use "==" because otherwise GDScript thinks you're trying to assign a value.

by (16 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 Frequently asked questions and 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 [email protected] with your username.