• RuntimesGodot
  • Incremental increase when animation is complete in Godot 4.4.1

hello all, hope everyone is well
I wanted to create a scene in godot 4.4 where my character increases a counter whenever a animation is finished. 2 animations are a idle(coolness) and attack as a test animation and they loop which is neccessary. Each animation has it's own label and would increase when the button for it was pressed to play and the animation completed.
I have attempted this doing it in script but could not find something to signal it. I also tried with an animation player calling the animation complete functions on their animations but did not work.

the script:
#this scene handles a animation
#animation can be changed via button

extends Node2D

@onready var onyx: SpineSprite = $Onyx

@onready var coolness_idle = $VBoxContainer/CoolnessIdle
var coolness_count := 0

@onready var attack_amount = $VBoxContainer/AttackAmount

func ready():
#onyx.get_animation_state()..connect(
on_animation_complete)
onyx.get_animation_state().set_animation("idle animation", true, 0)

func _on_idle_pressed():
onyx.get_animation_state().set_animation("idle animation", true, 0)

func _on_attack_pressed():
onyx.get_animation_state().set_animation("attack animation", true, 0)

func _on_Idle_animation_complete():
coolness_count += 1
coolness_idle.text = str("Amount of coolness = ", coolness_count)
print("idled")

func _on_Attack_animation_complete():
attack_amount += 1
attack_amount.text = str("Amount of attack = ", attack_amount)
print("attacked")

Guidance will be appreciated. I am completely stuck. Thank you

Related Discussions
...

To increment a counter when an animation completes in Godot, you need to connect the animation complete signal to your script. In your case, you should connect the animation_event signal from the SpineSprite to a function that checks for the completion of the specific animation. Here's how you can modify your script to achieve this:

extends Node2D

@onready var onyx: SpineSprite = $Onyx
@onready var coolness_idle = $VBoxContainer/CoolnessIdle
var coolness_count := 0
@onready var attack_amount = $VBoxContainer/AttackAmount
var attack_count := 0

func _ready():
    var animation_state = onyx.get_animation_state()
    animation_state.set_animation("idle animation", true, 0)
    onyx.animation_event.connect(_on_animation_event)

func _on_idle_pressed():
    onyx.get_animation_state().set_animation("idle animation", true, 0)

func _on_attack_pressed():
    onyx.get_animation_state().set_animation("attack animation", true, 0)

func _on_animation_event(sprite: SpineSprite, animation_state: SpineAnimationState, track_entry: SpineTrackEntry, event: SpineEvent):
    if track_entry.get_animation().get_name() == "idle animation" and event.get_data().get_event_name() == "complete":
        _on_Idle_animation_complete()
    elif track_entry.get_animation().get_name() == "attack animation" and event.get_data().get_event_name() == "complete":
        _on_Attack_animation_complete()

func _on_Idle_animation_complete():
    coolness_count += 1
    coolness_idle.text = str("Amount of coolness = ", coolness_count)
    print("idled")

func _on_Attack_animation_complete():
    attack_count += 1
    attack_amount.text = str("Amount of attack = ", attack_count)
    print("attacked")

Make sure that your animations emit an event named "complete" at the end of their timeline. This way, the _on_animation_event function will be triggered when the animation completes, allowing you to increment the counters accordingly.

Trying to understand where to place the signal, currently i have a node2d as the root main, the spinesprite attatched with a spine animation track as a child and a spinesprite track as a child of the spine animation node. I have implemented the script but not certain where to emit it correctly. sorry and thank you for trying to help me

edit:
sorry this is now resolved. I did not attatch any events in the spine editor, thought i could do it from code. This now works perfectly. thank you