• Editor
  • Mixing tutorial/documentation

Hey,

we're looking forward to use Spine in our next game and I've just started working with it in cocos2d.
Everything works pretty fine, however, there is one thing that is a little bit unclear.

It's mixing. What does it really do? Does it takes frames from the end of one animation and frames from the beginning of other one from the specified time converted to frames and then it blends those animations together?

Also, one thing would be good to know - when to clear animations?

There is absolutely no documentation on the cocos2d runtime at this time (or at least I haven't found any) and there is a lot of stuff that might be confusing for some developers.

I would love to write the documentation, if I knew how the spine runtime is actually working and what is actually happening.

Thanks,
Nick

Related Discussions
...
  • Đã chỉnh sửa

See the spine-c API:
https://github.com/EsotericSoftware/spi ... tion.h#L48

"apply" means to set the skeleton pose based on an animation. This ignores the current pose and overwrites it with the pose from the animation. "mix" means to set the skeleton pose somewhere between the current pose and the animation pose, based on the alpha parameter. It is used most often for crossfading when animations change, so the change is smooth.

You can clear your animation whenever you want. This means no animation will be applied, so the skeleton pose won't change.

Documentation will be coming. Would you rather have documentation and no runtime, or an undocumented runtime? 😉 😃

I didn't want to be rude or disrespectful by writing that there is no documentation.
I was just a little bit confused. Thanks for making it more clear 🙂

So, two last questions:
Mixing animations only changes pose and doesn't play any animation, right?

So the I should call it like this - play animation (looping, walk), then mix (walk–>jump), then play animation (jump), then mix again (jump–>walk) and play the animation again (walk, looping). Is that right? Or I should mix all the animation "transition" at the beginning (or between each animation change)?

Thanks and keep up with this great work!
Nick

No worries, I didn't think you were rude. Probably I often come across short, but it's just because I'm trying to do lots of stuff all at once. :$

Not sure what you mean exactly. Playing an animation is just posing your skeleton using an animation repeatedly over time. You can apply/mix animations yourself, or you can use the optional AnimationState convenience class. With AnimationState you set all the mix times beforehand, then when animations change it automatically mixes the old with the new animation. You never tell it "now mix", you just set the next animation.

Ok, I think I understand,
One last thing - what is the AnimationState convenience class and how to use it?

Yes, I have seen the C runtime, however it is really unclear.
Please, try to explain it a little bit, because as it is right now, it looks like you're the only one who can understand the code.

What is the difference between setAnimation:loop: and setAnimation:loop:forState: (and similar in all other functions)? What does the last parameter do? What would happen if I put 1 instead of 0 (default) into the state index?

And how do I switch between the animation states?

Well, I would actually like to know this as well.

I have trawled through the C code, all the examples, etc etc, and not found a single clue to why there are several states available. I can see each state is supposed to be updated on each tick, but the purpose of the states, still eludes me.
Since even the C files, are clinically cleaned for any comments, it really is hard to figure out what states are supposed to do.

Sorry again there are no docs. I pointed you to the class so you could take a look, but I'm happy to answer more specific questions if something is not clear. I should really write docs so I don't have to field questions, but I am anxious to get some editor features done. :tmi:

The multiple AnimationStates are applied each frame, one after another. You might want this if you are using multiple animations concurrently. Eg, you might separate the leg animations (standing, walking, running, etc) from the torso animations (idle, aim, shoot, etc) so you can mix and match. AnimationState uses "apply" (as described above) so keys applied by an AnimationState will overwrite any values from previously applied AnimationState. However, if an animation does not have keys for a value, that value is left unchanged. This allows you to apply two animations and as long as they don't key the same values, they won't stomp each other.

If SkeletonAnimation only had one AnimationState, you would have to subclass it and manage your own, second AnimationState. This is a bit clunky, so to better handle the case where you want to apply two AnimationStates, SkeletonAnimation keeps a list. You can specify the index in the methods. It starts at index 0. If you call addAnimationState then you can use index 1, etc.

We use state 0 for the main animation, 1 for facial expressions, and 2 for blinking.

When its time to play a main animation, like fire weapon, we stop the animation in state 1 and 2, play the main animation (which could have its own blinking, facial expressions), and then start them back up afterwards.

I'm not sure if this is a good or bad use of the state feature but it works for now.

Yep, that is the intended usage. It is helpful any time you want to apply multiple animations concurrently.

Thanks for all your help, almost everything is clear now.

Only one last thing - will the mix persist even after I play (add) an animation?
So, I could create all the mixes when initialising my class, and then only play with "add" and "set" animation?

Or will the mix "disappear" after I will add and play the animation?

Thanks,
Nick

Glad you are able to get by without proper docs. 🙂 The mix durations are stored, you set them up and they will be used until you change them. In fact, they are stored in AnimationStateData. You can create many AnimationStates all using a single AnimationStateData. This follows the same pattern as SkeletonData and Skeleton.

Thanks a lot Nate 🙂

4 ngày sau

Ok so I read all this how its suppose to work, but no code examples.
So from here I assume this:

torch->setMix("slidin","burn", 1.f);
torch->setAnimation("slidein", false);
torch->setAnimation("burn", true);

or:

torch->setAnimation("slidein", false);
torch->addAnimation("burn", true);

This is not allowing the animations to play concurrently, but instead sequentially or only the latter of two.

setMix sets crossfade durations. setAnimation sets the current animation. addAnimation queues animations to be played in sequence. To play multiple animations at the same time:

CCSkeletonAnimation* torch = ...
// Once during initialization:
torch->addAnimationState(); // Adds a second AnimationState.
// Then later to set your animations:
torch->setAnimation("slidein", false, 0); // first state
torch->setAnimation("burn", true, 1); // second state
13 ngày sau

Sorry to reopen this post, but I have a question:

Before to retrive the animation name I do that:

CCSkeleton * skeletonNode; //initialiaized
if(strcmp(skeletonNode->state->animation->name, "positon") == 0){
     //Do somthing when animation name is "position"
}

Now I tried the same with this:

CCSkeletonAnimation * skeletonNode; //initialiaized
AnimationState *state = [[skeletonNode states] objectAtIndex:0]; 

if(strcmp(state->animation->name, "positon") == 0){
     //Do somthing when animation name is "position"
}

But state->animation == nil. What I'm doing wrong?

Edit: I found where I'm wrong!!!

AnimationState *state = [[[skeletonNode states] objectAtIndex:0] pointerValue];
//too much hours in front of the mac...

Sorry for the question!

Yep! 🙂 The states have to be wrapped in an NSData. Kind of annoying. Maybe a getState🙁int)index method would be nice. Added!