using Spine.Unity;
using UnityEngine;
using Sirenix.OdinInspector;
[ExecuteInEditMode]
public class SpineAnimationScrubber : MonoBehaviour
{
[ShowInInspector]
private SkeletonAnimation skeletonAnimation;
[ShowInInspector]
[SpineAnimation]
public string animationName;
private float previousTime = 0.0f;
private float maxRange = 1.0f;
[ShowInInspector, PropertyRange(0.0, 1.0f, MaxMember = "@maxRange")]
private float currentTime = 0.0f;
private string previousAnimationName;
private Spine.TrackEntry anim;
private void OnValidate()
{
if( skeletonAnimation == null )
{
skeletonAnimation = GetComponent<SkeletonAnimation>();
}
if( skeletonAnimation == null ) return;
if( animationName != previousAnimationName )
{
anim = skeletonAnimation.AnimationState.SetAnimation(0, animationName, false);
maxRange = anim.Animation.Duration * 0.5f;
currentTime = 0.0f;
previousTime = -1.0f;
previousAnimationName = animationName;
} else if( anim == null && !string.IsNullOrEmpty( animationName ) )
{
anim = skeletonAnimation.AnimationState.SetAnimation( 0, animationName, false );
}
if( anim != null && currentTime != previousTime )
{
if( skeletonAnimation.state == null ) return;
anim.TrackTime = currentTime;
skeletonAnimation.Update( currentTime );
skeletonAnimation.state.Update( currentTime );
skeletonAnimation.LateUpdate();
skeletonAnimation.skeleton.Update(currentTime);
previousTime = currentTime;
}
}
}
I just needed something like this, so I made a simple animation scrubber. Could easily just update the current time OnInspectorGUI if you make custom inspector for it, but I had no need for that part.
I am sure the code can be optimized, but I didn't bother tbh.
Note: I am using OdinInspector for the PropertyRange attribute, but you can achieve the same dynamic range with a custom inspector.
Let me know if it helps 🙂