• Unity
  • AddAnimation only if nothing is queued

Hi there!

I'm currently using the End callback to queue an idle animation, however I only want to do this if other functions have not added to the queue. Is there a way to determine this? There is access to Tracks, but I'm not sure how to find if track 0 has any queued animations or not (not including the track that just finished).

Thanks!

Related Discussions
...

For example, if you are checking track 0.

TrackEntry currentTrackEntryOnZero = skeletonAnimation.AnimationState.GetCurrent(0);
bool trackZeroIsEmpty = (currentTrackEntryOnZero == null);

But yes, you also have access to the tracks. tracks are a list of linked lists of TrackEntries. The index is the track number. The list property (of type ExposedList<TrackEntry>) is named Tracks.

Thanks for the reply! So will GetCurrent(0) always return 0 in the Complete callback? Or can the animation that has just completed be counted here?

Complete has little to do with the TrackEntry being on the Track or not. It will fire in loop iterations and at the end of the formal animation duration, which is not necessarily when the animation will be removed from the track.
End is the event that signals when the TrackEntry will no longer exist on the track.

See also: Coding for Spine Events and AnimationState callbacks

Ok, makes sense! So I've changed this:

TrackEntry trackEntry = _spineAnimationState.SetAnimation(0, animation, false);
trackEntry.Interrupt += OnChangeActiveEquipmentAnimationInterrupt;
trackEntry.Complete += OnChangeActiveEquipmentAnimationComplete;

void OnChangeActiveEquipmentAnimationInterrupt(TrackEntry trackEntry) {
    trackEntry.Interrupt -= OnChangeActiveEquipmentAnimationInterrupt;
    trackEntry.Complete -= OnChangeActiveEquipmentAnimationComplete;

UpdateSkin(_activeEquipment);
}

void OnChangeActiveEquipmentAnimationComplete(TrackEntry trackEntry) {
    if (trackEntry != null) {
        trackEntry.Interrupt -= OnChangeActiveEquipmentAnimationInterrupt;
        trackEntry.Complete -= OnChangeActiveEquipmentAnimationComplete;
    }

UpdateSkin(_activeEquipment);

AddIdleAnimationToQueue(_activeEquipment);
}

to this:

TrackEntry trackEntry = _spineAnimationState.SetAnimation(0, animation, false);
trackEntry.End += OnChangeActiveEquipmentAnimationEnd;

void OnChangeActiveEquipmentAnimationEnd(TrackEntry trackEntry) {
    if (trackEntry != null) { trackEntry.End -= OnChangeActiveEquipmentAnimationEnd; }

UpdateSkin(_activeEquipment);

if (_spineAnimationState.GetCurrent(0) == null) { AddIdleAnimationToQueue(_activeEquipment); }
}

Can you see any issue with the logic? Basically before I was saying if the track was interrupted (another animation was set) don't play idle. Not I'm just checking to see if there's anything currently playing instead.

Edit: It appears End doesn't get called immediately on interrupt? Additionally interrupt seems to now being called almost immediately. How strange.

Edit 2: Ok, I see that End isn't actually called when an animation completes. Makes sense! I think I've figured it out, though I was closer with my original code.