• Runtimes
  • [Unity] Controlling animation playback speed

How are people controlling the playback speed of their animations?
I like the flexibility of using SetAnimation and tracks / mixing. However, I can't figure out a good solution to combine this with a variable playback speed per-track (for example, slowing down a Walk animation while playing a Blink animation over top at full speed).
Is there a way to do this? Or is the only option to set t he pose frame-by-frame in Update()? That seems extreme for what I want to do, and needlessly complex. Any examples? I was amazed there was no speed variable as an argument passed to SetAnimation.

Related Discussions
...

The SetAnimation method actually returns a Spine.TrackEntry object. Keep a reference to it if you want to change its playback speed over time.
Alternatively, you can use AnimationState's GetCurrent(int) to get the currently active TrackEntry object on a track number you pass.

The TrackEntry class has a field called timeScale that you can modify.
1f is normal speed. 0.5f is half speed. 2f is double speed. etc...

If change the speed is the only thing you want to do to the animation, you can go: SetAnimation(0, "animation", true).timeScale = 0.5f;
It won't return the TrackEntry object for the line anymore but you'll be able to do what you need to do in one line if that's all you need.

For more info, see : https://github.com/EsotericSoftware/spi ... te.cs#L255

Excellent! Thanks so much.

5년 후

what if I have crops which should grow over 2 hours. So when user first time opens the game we want to calculate remaining time and continue animation at that position?

This is then more about setting the playback timepoint - you can set the timepoint by TrackEntry trackTime. If you loop your animation, this will continue to increase across iterations, then you can query TrackEntry animationTime for the current iteration's time.

Keeping state between application exit and restart has to be done in your application logic (e.g. storing growth percentage state 59%), then you would need to start the animation and place it at the proper time:

SkeletonAnimation skeletonAnimation = this.GetComponent<SkeletonAnimation>();
var track = skeletonAnimation.AnimationState.Tracks.Items[0];
float currentPercentage = track.AnimationTime / (track.AnimationEnd - track.AnimationStart);
      
float storedPercentage = 0.59f;
track.TrackTime = storedPercentage * (track.AnimationEnd - track.AnimationStart) + track.AnimationStart;

Or you do it like in the SpineGauge example scene and have only a SkeletonRenderer instead of SkeletonAnimation and update the playback timepoint manually every frame/update:

growAnimation.Animation.Apply(skeleton, 0, percent, false, null, 1f, MixBlend.Setup, MixDirection.In);

thanks very much for clean explanation.

You're welcome. 🙂