How do I make other functions wait until animation ends?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Haseb
:warning: Old Version Published before Godot 3 was released.

Hi I’m creating a JRPG. I want to add some animation when characters get buffs/debuffs. I thought I could do it within setter functions of stats, so no matter when they get buffs/debuffs, animation is played. But it turned out quite difficult to stop other functions while animation is playing. I tried with yield and pausing game but I guess they’re not meant to be for this situation… Is there a better way to do this?

var power setget set_power

func set_power(value):
	power = value
	# play animation here
:bust_in_silhouette: Reply From: Michael Paul

Highlight the animation node, go to the inspector window, click the node tab, and you can see the available signal callbacks listed. Wire up the animation_finished() signal, and wait until it fires to start your other function calls.

Thank you for your reply! Let me ask some more. I think you’re talking about something like this:

func buff_power(character, value):
	character.power += value
	yield(AnimationPlayer, "finished")
	...

The problem is this will mess up the order when I call it from another function. How can I deal with this:

func powerup_and_heal(character):
	buff_power(character, 1)
	heal_hp(character, 10)

Should I always change stats from unnested function? Or should I nest yield each time a function is nested (like below)? Seems intimidating… What would you do if you were me?

func buff_power(value):
	...
	emit_signal("buff_power_finished")

func powerup_and_heal(character):
	buff_power(character, 1)
	yield(self, "buff_power_finished")

    heal_hp(character, 10)
    yield(self, "heal_hp_finished")
	...

Haseb | 2017-11-18 05:24

For example:

(...)
onready var animPlayer = get_node("AnimationPlayer")

func _ready():
	# you can do this in the editor too (animplayer's "node" tab -> signals)
	animPlayer.connect("finished", self, "myHandlerFunc")

func myHandlerFunc():
	if(animPlayer.get_current_animation() == "my_test_animation"): 
		print("Hey, the 'my_test_animation' animation finished")
	else:
		print("another animation finished")

(of course you have to launch an animation to test this)

bruteforce | 2017-11-18 13:18

Personally, I was thinking similar to what Bruteforce is doing. I tend to have a lot of other game aspects multitasking while animations are going on, so signals suit my style of game. Also, I like the idea of testing the AnimationPlayer to see if any animations in the container are currently running, but I’ve never gotten it to work.

Having said that… Yield would work well if you WANT to stop other aspects of the game until your animations are finished. Maybe something like:

#buffs are earned
get_node("AnimatedSprite1").play()
yield(get_node("AnimatedSprite1"),"finished")
get_node("AnimatedSprite2").play()
# etc

Michael Paul | 2017-11-18 14:07

I’m implementing the multiple yield method and it’s working so far. Not that hard, just one additional line for each buff. Thank you guys!

Haseb | 2017-11-20 01:34