• RuntimesGodot
  • Callbacks for SpineTrackEntry in Godot

I'm used to Unity where I can add Started/Completed/Interrupted callbacks per-track entry. It seems that Godot only has the option to receive these callbacks at the SpineSprite level. Is it possible to add these callbacks?

I'm aware that I receive the SpineTrackEntry in the callback, but it would be nice for cleanliness if I didn't have to check for it.

Related Discussions
...

In Godot, the SpineSprite node exposes signals for various animation state events, such as animation_started, animation_interrupted, animation_completed, animation_ended, animation_disposed, and animation_event. These signals can be connected to functions to handle the respective events. However, you are correct that these signals are at the SpineSprite level and not per SpineTrackEntry.

While you cannot directly set listeners on individual SpineTrackEntry objects in Godot, you can still achieve similar functionality by connecting to the SpineSprite signals and then checking the SpineTrackEntry within the connected function. Here is an example of how you can connect to these signals and handle them:

extends SpineSprite

func _ready():
    connect("animation_started", self, "_on_animation_started")
    connect("animation_interrupted", self, "_on_animation_interrupted")
    connect("animation_completed", self, "_on_animation_completed")
    connect("animation_ended", self, "_on_animation_ended")
    connect("animation_disposed", self, "_on_animation_disposed")
    connect("animation_event", self, "_on_animation_event")

func _on_animation_started(track_entry):
    if track_entry.animation.name == "your_animation_name":
        print("Animation started: ", track_entry.animation.name)

func _on_animation_interrupted(track_entry):
    if track_entry.animation.name == "your_animation_name":
        print("Animation interrupted: ", track_entry.animation.name)

func _on_animation_completed(track_entry):
    if track_entry.animation.name == "your_animation_name":
        print("Animation completed: ", track_entry.animation.name)

func _on_animation_ended(track_entry):
    if track_entry.animation.name == "your_animation_name":
        print("Animation ended: ", track_entry.animation.name)

func _on_animation_disposed(track_entry):
    if track_entry.animation.name == "your_animation_name":
        print("Animation disposed: ", track_entry.animation.name)

func _on_animation_event(track_entry, event):
    if track_entry.animation.name == "your_animation_name":
        print("Animation event: ", event.data.name)

In this example, the signals are connected to functions that check the SpineTrackEntry to determine which animation triggered the event. This approach allows you to handle events for specific animations without cluttering your code with checks for the SpineTrackEntry in multiple places.

While this method does not provide per-track entry callbacks directly, it offers a way to manage animation events cleanly within the constraints of the Godot engine.

Bad Spinebot 🙂

Sadly, callbacks on track entries is quite complicated to implement, as the underlying objects are actually native resources. I've opened an issue for this here:
EsotericSoftware/spine-runtimes2567

Will take a while to get this done, as I'm now working on making spine-godot an extension, which has priority.

10 giorni dopo

No problem, I appreciate the reply. GDExtension support for spine-godot is definitely higher-priority!