• Unity
  • mixing Timescale on different Tracks

I`m using Spine with Unity inkluding the Animator tool. For this i use this code:

public class AnimationScript : StateMachineBehaviour
{
    public string AnimationName;
    public float AnimationSpeed;
    public bool loop = true;
    public int track = 1;

private SkeletonAnimation anim;
//OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
    anim = animator.GetComponent<SkeletonAnimation>();
    anim.state.SetAnimation(track, AnimationName, loop).TimeScale = AnimationSpeed;
 
}

This works well so far. Now im trying to set the TmeScale for the walk animation to the real velocity of the Character.
I tryed by using:

public class AnimationScript : StateMachineBehaviour
{
    public string AnimationName;
    public float AnimationSpeed;
    public bool loop = true;
    public int track = 1;

public bool useRealSpeed= false;
private float currentSpeed;

private SkeletonAnimation anim;
//OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
    anim = animator.GetComponent<SkeletonAnimation>();
    anim.state.SetAnimation(track, AnimationName, loop);

    if (!useRealSpeed)
    {
        anim.timeScale = AnimationSpeed;
    }
 
}

override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{    
    if (useRealSpeed)
    {
        currentSpeed = animator.GetFloat("MovementSpeed");
        anim.state.TimeScale = currentSpeed * .5f;
    }
}

but it mess up the hole timesclae for other Animations too. I`m using two Tracks, 0 for Legs and 1 for Arms and Body.
Can anyone help me with that?

Related Discussions
...
5 jours plus tard

Currently, there are 3 sources of timescale on an instance of SkeletonAnimation.

  1. skeletonAnimation.TimeScale
  2. skeletonAnimation.AnimationState.TimeScale
  3. the TrackEntry timescale.

By default, all three have a value of 1, meaning the animation just plays at 100% speed.
These are combined multiplicatively. So if you set, skeletonAnimation.TimeScale = 0.5f and skeletonAnimation.AnimationState.TimeScale = 0.5f and SetAnimation(0, animationName, loop).TimeScale = 0.5f, you will get a speed of 0.5f * 0.5f * 0.5f which results in 0.125f.

So you have to decide which timescale you want to control and control it as you want.

Note that in your first OnStateEnter example, you are setting the TimeScale on a TrackEntry. Your code is equivalent to:

var trackEntry = anim.AnimationState.SetAnimation(track, AnimationName, loop);
trackEntry.TimeScale = AnimationSpeed;

The TrackEntry only lasts until that animation playback ends. And changing its timescale does not affect the timescale of other animations.

Where you used anim.timeScale, that's SkeletonAnimation.TimeScale, which is different from the first example.
Where you used anim.state.TimeScale, that's SkeletonAnimation.AnimationState.TimeScale which is also different from the other two examples.

Again, pick one of the three TimeScale values you want to control and control it sensibly, and/or understand how they combine and manage them as you need.

5 ans plus tard

I'm having the same problem, I got 2 animation on 2 tracks, I want to stop animation on track 1 while keep playing track 0
spine[i].spine.state.SetAnimation(0, spine[i].animation1, spine[i].loop1).TimeScale = 1;
spine[i].spine.state.SetAnimation(1, spine[i].animation2, spine[i].loop2).TimeScale = 0;

I used this code and both 2 tracks stop, still don't know how to do it correctly

This is a very old thread.

Setting the time scale on a track entry only stops that track. It will still be applied, so maybe it is overwriting the pose from the lower track. Clear the track if you want it to not be applied.