I recommend using SetAnimation. Its behavior is more predictable.
AnimationName
is just a property detached from the thing that's actually playing the animation.
Changing it plays a new animation. If you say AnimationName = jumpAnim
and AnimationName
was already == jumpAnim
. It won't do anything.
SetAnimation
will search for the animation with the name you gave it, then play that animation.
Fundamentally, it functions very differently from AnimationName = x
skeletonAnimation.state
is the actual thing managing the progression of the animation.
When you call SetAnimation, the animation starts playing from the beginning.
But your controller logic is flawed for that.
It's actually flawed for other uses too. You'll fix that yourself, I guess.
But if it says
void Update () {
if (!isOnGround) {
skelAnim.state.SetAnimation(0, jumpAnim, false);
}
}
Whatever is inside Update gets called every frame.
It keeps calling SetAnimation,
SetAnimation keeps playing the animation from the beginning,
and you end up seeing is the first pose of the animation every frame.
This is closer to what you want:
void Update () {
if (!isOnGround) {
MySetAnimation(jumpAnim, false);
}
}
// Non-overriding SetAnimation stump
void MySetAnimation (string animationName, bool loop) {
const int TRACK = 0;
var state = skelAnim.state; if (state == null) return;
var current = state.GetCurrent(TRACK);
if (current == null || current.Animation.Name != animationName) {
state.SetAnimation(TRACK, animationName, loop);
}
}
But this is just to get it working.
If you're making something that controls animation, it needs to detect changes in the character's state, and make sure to change the animation only at the points when the state changes. This is pretty much true anywhere, even if it's done for you implicitly.
Spine's AnimationState doesn't take that route since it's designed to be flexible and its uses still spans a pretty broad range of animation control styles.