gumboots

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!
gumboots
Posts: 35

Pharan

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.
User avatar
Pharan

Pharan
Posts: 5284

gumboots

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?
gumboots
Posts: 35

Pharan

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
User avatar
Pharan

Pharan
Posts: 5284

gumboots

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.
gumboots
Posts: 35


Return to Unity