Can I set animation_finished signal for only one animation?
Asked Answered
F

6

0

I have a character after a jump, has a landing animation, this needs to play, before an idle state (in state machine) gets called with the animation_finished signal.

This Idle state, has a secondary Idle state supposed to kick in after 5 seconds, but, after the Idle animation is played on a loop, the signal is fired and the character goes back to the start of the Idle state again, the secondary Idle never gets a chance to kick in.

This is what the finished signal is set to do...

func _on_AnimatedSprite_animation_finished():
		var target_state: = "Move/Idle" if get_parent().get_move_direction().x == 0 else "Move/Walk"
		_state_machine.transition_to(target_state)
~~~	
This function is ONLY in the Landing state, but the signal seems to be universal, and triggers anyway again  in the Idle state.

Is there a way to specify the signal to only trigger on a specific animation ending, Land, in this case, and not when any other animations have finished?
Frambesia answered 29/11, 2020 at 2:32 Comment(0)
A
0

*Edit: See further post, this is wrong.

Rather than make it only fire once, just include an IF that captures which animation just finished in the signal:

func _on_AnimatedSprite_animation_finished(anim_name):
	if anim_name == "landing":      # whatever you called it
		Do Stuff here

Sidenote, that syntax for declaring target_state works?

Sidenote #2, I don't know how your state machine is written, but I don't think you want to be calling a state machinie function in the animation signal in general. It could/may work depending on how everything else is written, but I think in this for example if the player landed (causing the landing animation) and instantly jumped straight up again, _on_AnimatedSprite_animation_finished would fire while the player is jumping, and as x would still be 0, suddenly your idling in midair (perhaps only for a frame depending on how your jump works, but regardless).

I am not the knowledge on such things, but I thought all state logic should be handled by 'state_machine', which is essentially checking a bunch of variables every delta to confirm the current state based on your conditions. Using this approach, the animation signal would simply toggle a 'landing_anim_playing' variable from True/False, then the state_machine code would check this. Otherwise tracking down what caused a state change becomes more painful than it already usually is lol.

Aconite answered 29/11, 2020 at 6:1 Comment(0)
F
0

Yeah, thats what I thought, only I get an error...

_on_AnimatedSprite_animation_finished': Method expected 1 arguments, but called with 0..

....if I give the function an 'anim_name' argument and then chuck in the if statement if anim_name == "Land":

Is the signal passing back the actual name of the animation thats just finished playing, or just the fact that one is finished playing?

Im trying to move on from the tutorials in the GDQuest 2D Platformer course, so yes this syntax works, its part of the course!

Thing is, i ONLY want the animation to play during the land state, no movement, no option to jump instantly etc. (if you jump off a chair, your knees need to bend and straighten again before you can jump or move, its pyhsicaly impossible to do otherwise - the character needs to reflect that), its only a 3 frame animation at 15 fps, so its real short. I have another animation for turning which will need to work the same way, once I figure this one out!

Once this animation has finished, THEN, and only then, we can move on to the next state.

Frambesia answered 29/11, 2020 at 13:8 Comment(0)
A
0

Literally just noticed your using 'AnimatedSprite' and not the 'AnimationPlayer' node so I apologise, my code won't work.

I havn't dabbled in 2D at all so don't know the 'correct' way, but I would attach an AnimationPlayer node and run the sprite node from it (like this, but don't click loop:

that way gaining access to the 'finished' signal from the AnimationPlayer node, where it does pass the name of the animation.

The alternative I guess would be to have multiple sprite nodes and control visibility on finish?

Aconite answered 29/11, 2020 at 22:32 Comment(0)
F
0

Thanks for your reply, yes, it seems I need to take a more indepth look at AnimationPlayer rather than AnimatedSprite. I'll post an answer back here once I figure it out!

Frambesia answered 2/12, 2020 at 21:39 Comment(0)
S
0

A little late but for anyone else who finds this, the first solution by BimBam works just fine (at least for my setup it does). You just have to get the current animation a little differently. Instead of it being passed as a parameter you can just do

func _on_AnimatedSprite_animation_finished(): 
    if ($AnimatedSprite.animation == "animName"):
        #do stuff
Saleh answered 20/5, 2021 at 15:7 Comment(0)
L
0

Saleh Thanks for this! :

Lyns answered 5/3 at 2:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.