• Unity
  • Animation Update That Handles Events

In order to improve performance in my game I've edited SkeletonAnimation to not perform an Update when an object is off-camera:

void Update() {
    #if UNITY_EDITOR
    if (!Application.isPlaying) {
        Update(0f);
        return;
    }
    #endif

if (meshRenderer.isVisible) {
    Update(Time.timeSinceLevelLoad - lastUpdateAt);
    lastUpdateAt = Time.timeSinceLevelLoad;
}

All fine and good. With one exception! I'm using Spine Events to trigger certain things at the right time in an animation, but those Events won't get processed if the Timeline.Apply(...) never gets called by an Update(deltaTime) that never happens. A character wanders off camera and begins to perform some action which would ordinarily call some event, but because meshRenderer.isVisible != true the events never surface and the character gets stuck.

I am wondering - is there a customisation I can make to the Spine Unity runtime that allows for an Update that isn't so performance heavy, ie; all it does is process Event tracks in an animation? I'm not very familiar with the guts of the runtime to know if that's an easy thing to do, or just an uphill battle against Spine's core design.

Perhaps I'm tying too much critical logic into the animations themselves, but events are such a workflow-friendly way of timing things to an animation! And I care about that timing when these characters are on camera. I should very much like to not update my animations when a character is off-screen... but also listens to events.

What would be the right solution for me here, maintaining performance and my existing event-based logic?

Related Discussions
...

It should be very easy. Here is the code that applies all the timelines for an animation:
https://github.com/EsotericSoftware/spine-runtimes/blob/3.8/spine-csharp/src/Animation.cs#L82-L84

What you want to do is: when off-screen, only apply timelines that are an EventTimeline. The only other piece you need is what animations to do this to. For that you can use the Tracks field on AnimationState:

ExposedList<TrackEntry> tracks = animState.Tracks;
for (int i = 0, n = tracks.Count; i < n; i++) {
   TrackEntry entry = tracks.Items[i];
   Animation animation = entry.Animation;
   // Iterate timelines, apply if EventTimeline.
}

Thanks for sharing the idea! Currently we have the Advanced - Update When Invisible mode parameter that goes in a similar direction, however it currently provides these update modes:

Nothing,
OnlyAnimationStatus,
EverythingExceptMesh,
FullUpdate

To this enum we could add your mode as OnlyEventTimelines which would then apply the event timeline playback.


This feature has just been implemented. SkeletonRenderer components now provide an additional update mode Only Event Timelines at the Advanced - Update When Invisible property. This mode saves additional timeline updates compared to update mode Everything Except Mesh.

A new 3.8 unitypackage can be downloaded here as usual:
Spine Unity Download

Please let us know if this works as intended for you!

Issue ticket URL for later reference:
https://github.com/EsotericSoftware/spine-runtimes/issues/1815

:bigeyed:

Wow, thanks guys!! A shiny new feature that's just for me (at least right now I'm probably the only one using it). And I can confirm it works perfectly. I had absolutely missed the 'Update When Invisible' option, I don't know if that's a recent update or I just never noticed it, but ideal for me to have those options without needing to dig into the runtime.

You guys rock. 🙂

Thanks for your kind words, glad you like it! 8) Well, we hope it's not only useful for you. 😉

Admittedly the missing event-preserving update mode is pretty important, we just haven't thought of that during the initial implementation of the Update When Invisible feature. Correct implementation respecting transitions is not completely trivial, so it makes sense to provide it at the right place (AnimationState) instead of trying to wrap it around from the outside.

I had absolutely missed the 'Update When Invisible' option, I don't know if that's a recent update or I just never noticed it, but ideal for me to have those options without needing to dig into the runtime.

The general Update When Invisible feature was added on 2020-08-05, so it has only been around for a few months.