• Bugs
  • Unity: One frame of wrong animation

Related Discussions
...

In my Unity runtime, when I create a spine enabled game object, sometimes I see the object render for one frame of the entirely wrong animation. I've tracked this down to:

SkeletonAnimation.cs

[SerializeField]
private String
   _animationName;

I thought it was curious that this field was serialized, and it appears that the reason is that the inspector pokes it for animation, perhaps for animation preview functionality?

SkeletonAnimationInspector.cs

component.AnimationName = selectedAnimationName;

The name serialized in _animationName then appears to be used during the Awake and Reset code paths.

Spine.AnimationState:SetAnimation(Int32, Animation, Boolean) (at Assets/Add-ons/Spine/spine-csharp/src/AnimationState.cs:200)
Spine.AnimationState:SetAnimation(Int32, String, Boolean) (at Assets/Add-ons/Spine/spine-csharp/src/AnimationState.cs:189)
SkeletonAnimation:Reset() (at Assets/Add-ons/Spine/spine-unity/Assets/spine-unity/SkeletonAnimation.cs:92)
SkeletonRenderer:Awake() (at Assets/Add-ons/Spine/spine-unity/Assets/spine-unity/SkeletonRenderer.cs:147)
UnityEngine.Object:Instantiate(Object, Vector3, Quaternion)

starting with the code in SkeletonAnimation.Reset()

public override void Reset () {
   base.Reset();
   if (!valid)
      return;

   state = allocateAnimationState(skeletonDataAsset.GetAnimationStateData() );  // Spellbind Edit
   if (_animationName != null && _animationName.Length > 0) {
      state.SetAnimation(0, _animationName, loop);
      UpdateSkeleton(0);  // Spellbind Edit
   }
}


When that's all happening ... later in my own code after the object instantiation I decide to play a different animation, in my case it's a "summoned" animation. The result is that for one frame I see the object in the idle pose/animation, and then the summon animation plays.

The fact that I have a mix between my idle and summoned animation of 0 doesn't seem to help the situation, only making the _animationName field not serialized makes the issue go away for me.

If indeed the _animationName field is supposed to be serialized (maybe this is how you intend to set a default animation for an object?), there seems to be difference of some kind when this is done during initialization and when the exact same thing might be done by the user later. For instance, even in my summoned case I am actually saying

1) Instantiate
2) Play idle
3) Play summoned

But everything is OK for me as long as _animationName is not serialized. Certainly this breaks some inspector functionality ... what's the right thing here to be looking at?

SkeletonAnimation.cs

// [SerializeField] // SPELLBIND EDIT, breaks some inspector functionality
private String
   _animationName;

Perhaps a better thing would be to null this field for the runtime only?

SkeletonAnimation.cs

// SPELLBIND BEGIN
public override void Awake()
{
    if (Application.isPlaying == true)
    {
       _animationName = null;
    }
    base.Awake();
}
// SPELLBIND END

Thanks much.

That serialization is a hold over from before I came on scene. Good catch. I'll do something smarter, and probably rip out all of the picker stuff from SkeletonAnimation in general and replace it with the SpineAttribute system soon. Will definitely add instantiation testing to my testing 🙂

Yeah, this is an old bug. Annoying as hell.

5 mjeseci kasnije

I encountered this bug earlier today, where in the very last frame of a mix, the animation will display a completely different frame. I tried the fix colinday suggested, getting rid of the SerializeField, but no change. I suppose in the last five months the code has moved on.

I think I've found the problem though, and submitted a fix here - EsotericSoftware/spine-runtimes490

It sorts out the issue for me.