Animated sprite animations using animation_finished loop on timer

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Kutkulio

I’m trying to make a simple enemy that sits in an idle animation and shoots every so often. It’s supposed to play a firing animation when the timer goes off then revert to its idle until the timer goes off again.

What actually happens is it will cycle through once back to the default animation then get stuck. I’m still new, if there’s a better way to go about this I’d be happy to hear it. Thanks!

func _physics_process(delta):
	
	if can_shoot == true:
		$AnimatedSprite.play("firing")
		$AnimatedSprite.connect("animation_finished", self, "_on_firing_animation_finished")
		emit_signal('shoot', Bullet, $Position2D.global_position)
		can_shoot = false

func _on_firing_animation_finished():
	$AnimatedSprite.play("default")
	$GunTimer.start()

func _on_GunTimer_timeout():
	can_shoot = true

Does the timer loop (IIRC, a Timer node loops by default)? If so, each time the timer ends, play the animation. The function could like like this:

func _on_GunTimer_timeout():
   $AnimatedSprite.play("firing")
   emit_signal('shoot', Bullet, $Position2D.global_position)

func _on_firing_animation_finished():
   $AnimatedSprite.play("default")

Make sure that the “firing” animation doesn’t loop, and the above code should work.

Ertain | 2020-06-17 18:43

I’m not 100% sure why, but shuffling everything around the timer worked. Doing so eliminated the can_shoot variable as well. The original setup was simple enough, I’m still not sure why it didn’t work originally. New code is below. Thanks for your help!

Edit: Is it possible to emit the shoot signal on a certain frame of animation? I made a 20 frame animation of a minigun spooling up, shooting, then spooling down and I just want to time a burst in the middle.

func _on_firing_animation_finished():
	$AnimatedSprite.play("default")

func _on_GunTimer_timeout():
	$AnimatedSprite.play("firing")
	$AnimatedSprite.connect("animation_finished", self, "_on_firing_animation_finished")
	emit_signal('shoot', Bullet, $Position2D.global_position)
	$GunTimer.start()

Kutkulio | 2020-06-17 18:54

You could try inserting a call to a method in an AnimationPlayer for the minigun. There’s details of adding a method call to an AnimationPlayer in the Godot engine documentation.

Ertain | 2020-06-17 19:22