How do I stop a Tween's animation outside of its scope?

I want my player to swing a weapon - to do this I use a Tween and do tween.tween_property() on it. This works perfectly fine until I swing the weapon again before the animation is finished (the cooldown for attacking is lower than the length of the animation). Here’s the function called every time the player swings the weapon:

func attack():
  var tween = create_tween()
  tween.set_ease(Tween.EASE_OUT)
  tween.set_trans(Tween.TRANS_CIRC)
  $Weapon/Sprite.rotation = -PI                                  # set the rotation to negative
  tween.tween_property($Weapon/Sprite, "rotation", PI / 2.0, 0.5) # then make it go to positive
  tween.tween_property($Weapon/Sprite, "rotation", 0, 0.0)         # and finally, reset to 0

What happens when I swing before the tweening is finished is: the rotation just stays at PI / 2.0 then resets to 0 after 0.5 seconds. My understanding is that the tweening works and rotation goes to PI / 2.0 in 0.5 seconds just as I want it to but it doesn’t reset to -PI because the previous tween is still going, so nothing happens visually. How could I stop the previous tween so that I can effectively reset rotation to -PI and swing the weapon as desired? Thanks for any help!

P.S: I know that the function tween.kill() stops the tween, but I can’t call it on the tween because I don’t have any reference to it! Tried making the tween global but that didn’t work (just can’t do that).

Godot 4.2.1.stable

What happened?

I would make a global var attack_tween : Tween

Just need to make sure it’s updated.

It will start off null until the attack.

func attack():
  If attack_tween: 
      attack_tween.kill()
      attack_tween.free()
      attack_tween = null
  var tween = create_tween()
  tween.set_ease(Tween.EASE_OUT)
  tween.set_trans(Tween.TRANS_CIRC)
  $Weapon/Sprite.rotation = -PI                                  # set the rotation to negative
  tween.tween_property($Weapon/Sprite, "rotation", PI / 2.0, 0.5) # then make it go to positive
  tween.tween_property($Weapon/Sprite, "rotation", 0, 0.0)         # and finally, reset to 0
  attack_tween = tween
2 Likes

This works almost perfectly, only had to remove the free() because it threw an error: “trying to free a reference” or something like that. Thanks!

1 Like

I guess resources are reference counted, you don’t need to free them explicitly.