• Unity
  • Sometimes (Randomly) Animation Completes Almost Instantly

Howdy!

I have an interesting issue. My code is setup in such a way that the next animation will not play until the current one is finished.

However, sometimes (and I cannot reproduce this reliably) an animation finishes near instantly.

My current animations take about 0.5-2 seconds, however I am getting a complete callback (sometimes) after a few milliseconds.

Here is a log example of the bad timing (its completing after a few milliseconds):

[Log] Started Animation attackMainWeapon timestamp: 17.28275
[Log] Animation Complete: attackMainWeapon timestamp: 17.36266

Here is a good log example of good complete callback finishing (it completes after the full animation)

[Log] Started Animation attackMainWeapon timestamp: 14.98926
[Log] Animation Complete: attackMainWeapon timestamp: 15.66332

Here is my custom code for setting up the completion callback, if you see anything please let me know (I would GREATLY appreciate a hint as to what I might have done wrong here).

public class UnitAnimator : MonoBehaviour
{
   public AnimationCompleteCallback animationCompleteCallback;

   protected AnimationStateData _animationStateData;
   protected SkeletonAnimation _animator;
   protected Spine.AnimationState _baseState;

   private S_EffectEvent _data;
   private string _currentAnimation;

   public void Start()
   {
      _animator = GetComponentInChildren<SkeletonAnimation>();
      _baseState = _animator.state;
      _baseState.Complete += delegate (TrackEntry entry) 
      {
         AnimationComplete();
      };
   }

   public void AnimationComplete()
   {
      if (_data == null)
      {
         return;
      }

  Debug.Log("Animation Complete: " + _currentAnimation + Time.time);
  _data.activeAnimationObjects.Remove(gameObject);
   }

   public void PlayAnimation(string  t_unitAnimation, bool loop, S_EffectEvent data = null)
   {
      _currentAnimation = t_unitAnimation;

  Debug.Log("Started Animation " + t_unitAnimation + Time.time);

  if (data != null)
  {
     _data = data;
     _data.activeAnimationObjects.Add(gameObject);
  }

  _baseState.SetAnimation(0, t_unitAnimation, loop);
   }
}
Related Discussions
...

Your log doesn't seem to be correctly indicating what's going on.

Debug.Log("Animation Complete: " + _currentAnimation + Time.time);

Spine.AnimationState's Complete will fire the Complete event when a TrackEntry completes, and it gives you that TrackEntry reference.
But you're logging _currentAnimation, the string stored in your MonoBehaviour, not the TrackEntry it gave.
Many times, during mixing, these can be different animations.

Check against the TrackEntry.Animation.Name or something to be sure you are handling the Complete event you're looking for.
Even if you say you only play new animations when the previous one completed, that may not be what your code is actually achieving so _currentAnimation becomes incorrect when that is also incorrect.

As you predicted when I log vs the Track.Entry.Name the completion of a different animation is causing the issue:

[Log] Started Animation attackMainWeapon 6.083514
[Log] Animation Complete: idleTwoWeapons 6.202386

The name from the track entry is not the same as the animation I called (basically, sometimes, the previous animation is calling the next animations completion handler). Thank you for this critical insight. I will now check that the track complete matches the animation I set before firing its callback like so:

public void AnimationComplete(TrackEntry entry)
{
   // The completion of the Idle (or another animation) can cause an almost instant completion of the animation. So make sure the _currentAnimation
   // name matches the track name
   if (_data == null || entry.Animation.Name != _currentAnimation)
   {
      return;
   }

   Debug.Log("Animation Complete: " + entry.Animation.Name + Time.time);
   _data.activeAnimationObjects.Remove(gameObject);
}

I can't say I completely understand your logic, but do you really need to check whether "_data" is null every time an animation completes?