• Runtimes
  • [Unity] Sprite order problem

Hi,

In our animations, we change depth order a lot, and change sprites state too.

In scripts, when I call skeleton.SetAnimation(), sprites order and state are not set correctly unless our animators explicitly change all depth order and sprite state in every single animation, which is a real pain.

To avoid this problem, I call skeleton.SetBonesToSetupPose and skeleton.SetSlotsToSetupPose() to reset the skeleton.

BUT, doing this causes the skeleton to be drawn during one frame in a "neutral pose".

What is the right way to change the animation, and keeping the right sprite state and depth order ?

Thanks.

Related Discussions
...
  • Изменено

SOLUTION 1:
Assuming you want it to look like what it looks like in Spine editor and aren't doing combinations of animations at runtime, you can do a standard autoreset.

In that script managing the animations,
Assuming skeletonAnimation is a reference to the SkeletonAnimation component, and skeleton is a reference to its Spine.Skeleton
you can say, maybe somewhere in Start:

skeletonAnimation.state.Start += delegate {      skeleton.SetToSetupPose();      };

SOLUTION 2:
If that doesn't achieve what you need, you could probably give Skeleton.cs a SetDrawOrderToSetupPose method and use that.
That new method in Skeleton.cs would look something like this:

public void SetDrawOrderToSetupPose () {
   List<Slot> slots = this.slots;
   drawOrder.Clear();
   drawOrder.AddRange(slots);
}

This is likely only in the event that you do something mildly complicated with animations. If you don't, the first solution is likely enough.

In scripts, when I call skeleton.SetAnimation(), sprites order and state are not set correctly unless our animators explicitly change all depth order and sprite state in every single animation, which is a real pain.

Sorry, this sounds like the solution to me. If you have an animation that has a specific draw order it should be keyed as such IMO.

Spine's a bit confusing for a new user this way.
Animators expect it to look like it's supposed to look in Spine Editor. But Spine editor autoresets the skeleton whenever you play an animation or switch, while the runtime doesn't assume that this is what you want.

Using the logic of "key it if you want to be sure that's how it starts", a user would (and I've seen people do) key every scale, rotation, translation of every bone and every slot attachment and mesh vertices and pretty much the whole setup pose at the beginning of every animation, just to be sure that if any of them were changed by other animations, that the animation would still look like the way it was animated in Spine editor.

I've seen a good number of people do this, and it's terrible to work with in the editor with all the extra timelines, and performance scales horribly at runtime.

(Actually, their reasons for doing this isn't just for resetting the skeleton.
Some people do this so it's simple to copy exact poses from one point in time to another, or between animations.)

But you're right. If it's just the draw order, I guess one extra timeline isn't a problem on either side.
But it is one extra thing to add to who knows how many animations. It's probably not an unsurmountable problem in that sense.

If the behavior you need is for the skeleton to use the setup pose draworder unless otherwise specified, the method to reset the draworder will do the job without having to make sure stuff is keyed in Spine editor.

Hello,

Thank you for your very fast answers !

Calling skeleton.SetToSetupPose(); in skeletonAnimation.state.Start event doesn't help. There is still that bad looking frame.

Maybe skeleton.SetToSetupPose(); is not done early enough in the frame.

The ideal scenario would be to call skeleton.SetToSetupPose(); THEN have the first keyframe of the animation rendered within the same frame, so that we don't see that bad looking frame.

Any ideas ? Otherwise we will have the artists key things.

I kinda see where the problem might be. There's a chance that the script calling SetAnimation might be Updating later than SkeletonAnimation.

Try adding it to state.End instead of state.Start.

This is starting to sound weird to me though. But see if it works.
The downside to this is that it will reset if it plays a non-looping animation with nothing that follows.

Are you using crossfading/mixing?

Thank you for your help Pharan.

It is now fixed. We are still using state.Start and we now make sure SkeletonAnimation is the last script called in the script execution order of unity.

Thank you all for your answers !