• Runtimes
  • How to change the drawOrder in SkeletonAnimation ?

I have a character skeleton animation with some canon in the Spine Editor . One canon in front of the character and the others behind . Now I output (character.json) and (canon.json) . Import to the unity like this :

canon.json

character.json

And set the canon's parent to the character :

Bone canon = _canon.skeleton.FindBone("root");
Bone character = _character.skeleton.FindBone("bone");
character.parent = canon ;

But the drawOrder is incorrect . How to make sure it remains consistent ?

The bone hierarchy is just for transformations. Unity Scene graph specifies the draw order. Change the cannon position in the scene hierarchy.

But the canon and the character animation's drawOrder has adapted in the same project of Spine Editor . I just moved the canon to other project . I think the programmer to do the same thing (to change drawOrder again) is not a good idea . How can we make the canon automatic to adapt the character ?

I noticed that the canon's json have a drawOrder node :

"drawOrder": [
         {
            "time": 0.8,
            "offsets": [
               { "slot": "fire_point3", "offset": 9 },
               { "slot": "fire_point4", "offset": 9 }
               ... ...
            ]
         }
      ]

Can we use this node to solve the problem ? Or do you have a better way ?

Ok, let me see if I understand you correctly.

All 3 cannons = 1 animation? In which case you're trying to interleave two animations?

You want to draw two of the cannons/slots in the BG, draw the character, and then draw the last slot/cannon in front?

I thought you were looking at 3 instances of Cannon and a single instance of the character, but this is not correct. Truth?

jpoag wrote

All 3 cannons = 1 animation? In which case you're trying to interleave two animations?

You want to draw two of the cannons/slots in the BG, draw the character, and then draw the last slot/cannon in front?

Yes , you 're right .

Simple Options:

  1. Add empty slots for weapons to character animation. Animate weapons slots according to weapon class {blaster, rifle, cannon, etc...}. Add Attachments to slots only when weapon equipped. See Goblins Demo.

  2. Split the Canons animation in Half [Editor], render : Canon_1_2, Character, Canon_2_2

  3. Duplicate the Cannon animation, clear the slot attachment(s)

    , render: Canon_No_Front, Character, Canon_No_Back[/*][/list]
    #1 is how Spine is designed to work.
    
    
    
    Complex Options:
    [list=1]
    [*]Use [url=https://github.com/EsotericSoftware/spine-runtimes/blob/master/spine-unity/Assets/spine-unity/SkeletonRenderer.cs#L215]zSpacing[/url] on Meshes, add 'zOffset' and pray that MeshRenderer sorts submeshes by zOrder in the transparent layer.[/*]
    [*]Complete SkeletonRenderer rewrite[/*][/list]

I saw the Goblins Demo . But the Canon is not a attachment but a animation with bones . Even with a whip animation as a weapon . You can see the canon play Fire Animation with effects one by one .

I need to use the weapon animation to diffrent characters . It's more flexibility for Game . I will create more weapons with animations and effects to other characters .

Bone canons = _canon.skeleton.FindBone("root");// three canon's root bone .
Bone hand= _character.skeleton.FindBone("hand");
canons.parent = hand;// any weapon to any character .

Now every thing looks perfect except the drawOrder .
I wish Spine can solve the problem perfect in the future . 🙂

Sadly this isn't a trivial problem heh; I've been thinking of a few ways to solve it involving submesh renderers and using the DrawOrder of a given slot to influence Unity's "Order in Layer" property for z sorting. Its ugly and complicated though.

Here's a video of how a little bit of that works.

This functionality is all in the runtimes if you want to leverage it. Take specific note of how asterisks * are used to generate new mesh renderer passes.

Mitch wrote

Sadly this isn't a trivial problem heh; I've been thinking of a few ways to solve it involving submesh renderers and using the DrawOrder of a given slot to influence Unity's "Order in Layer" property for z sorting. Its ugly and complicated though.

I agree. Not only is it non-trivial, but I think this specific use case adds further complexity. I'm guessing the character is the prime asset (root object) and the canons are subordinate. If it were the other way around I would suggest an empty slot in the canons animation to draw the character. As it is now... well... yeah.

You need to literally interleave two animations.

[EDIT] : The following is not possible because of how draw offsets are handled.[/EDIT]

I think a general solution is as follows: create a container (SkeletonList/Renderer) that collects all the slots from all the animations that it contains and sorts by *submission order and *spine-draworder.offset.

Your animations in Spine can use negative and positive draworder.offsets, and still retain a relative order. The trick is to use [a Stable Sorting Algorithm, such as BubbleSort] when merging the draworders. Add the new draw orders to the end of the list and [stable]sort.

Image removed due to the lack of support for HTTPS. | Show Anyway

It's a general solution because it doesn't require any specific renderer or runtime to operate. SkeletonList would automatically collect and sort slots when an animation is added to it or during an update() phase (is there a draw order timeline)? Then, instead of iterating the slots in the skeleton, you iterate slots in a skeleton list.

Unity would need a little more work as you would need to add the Spine Animation to the SkeletonList/Render instead of to the scene graph. But for this user case, the SkeletonList would be the root object and they could add/remove skeleton animations as they wished.

Mitch wrote

This functionality is all in the runtimes if you want to leverage it. Take specific note of how asterisks * are used to generate new mesh renderer passes.

I've only seen the submesh '*' trick rendering in Unity. I checked the other renderers and could not find it. It's dependant on how a renderer works, Unity uses a scene graph which does a lot of sorting and render state optimizations. A lot of other renderers issue render commands immediately.

Time is running out in our company . So , our temporary solution is looks like the Goblins Demo. But ninety weapons in each character makes the memory very high . I don't know when has this feature in Spine . If the issue will be solved , where can I see the message ?

Why don't you create a single skeleton with the weapon and then at runtime draw that skeleton three times ? You could use empty bones/slots as indicators of where you want the weapons to appear.

I will reply to this in a few hours but it won't be a pretty solution.

Shiu wrote

Why don't you create a single skeleton with the weapon and then at runtime draw that skeleton three times ? You could use empty bones/slots as indicators of where you want the weapons to appear.

I've tried it . But the two questions I havn't solved:
1.Not all of Weapons like the canon . For example , the AK-47 , I want it in front of the character body and behind the right arm . So , it is impossible to create a single skeleton with the right arm . Even the whip weapon , I want it behind the character in some frames and in front of the character in other frames .

2.The material's renderQueue make me confused . I put two biliboard in front of the mainCamera . The A biliboard material.renderQueue = 1000 and the B biliboard material.renderQueue = 2000 and there transform Z are equal same value , so I saw B in front of A . But I use the character instead of A and the Canon instead of B , I saw a strange phenomenon . When I just decrease the Canon's value of transform X , it is behind the character . And then , I increase transform X , it is in front of the character . The phenomenon was not appear in the biliboard case . Do you know what's the problem ?

http://www.xdtech.net/spine/Spine_DrawO ... eleton.zip
(See example scene and spine source files)

Here is how I would accomplish this. Take specific note of how the Events are used to push specific slots forward/backward in the sorting order.

public class SubmeshOrderInLayer : MonoBehaviour {

   SkeletonAnimation skeletonAnimation;
   SkeletonUtilitySubmeshRenderer[] renderers;
   
void Start () { skeletonAnimation = GetComponent<SkeletonAnimation> (); skeletonAnimation.state.Event += HandleEvent; renderers = GetComponentsInChildren<SkeletonUtilitySubmeshRenderer> (); } void HandleEvent (Spine.AnimationState state, int trackIndex, Spine.Event e) { if (e.Data.Name == "OrderInLayer") { int index = skeletonAnimation.skeleton.FindSlotIndex(e.String); renderers[index].sortingOrder = e.Int; } } }

I know it sucks 🙁 but its what i've got for your unique situation at the moment. Goodluck! :S

I've only seen the submesh '*' trick rendering in Unity. I checked the other renderers and could not find it. It's dependant on how a renderer works, Unity uses a scene graph which does a lot of sorting and render state optimizations. A lot of other renderers issue render commands immediately.

Heh yea; his screenshots had Unity stuff in it so I was addressing it in terms of Unity 🙂 Sorry for confusion.

Mitch wrote

Heh yea; his screenshots had Unity stuff in it so I was addressing it in terms of Unity 🙂 Sorry for confusion.

You got my hopes up is all, thought I'd missed a secret feature.

Nice hack, btw. 8)

Mitch wrote

I know it sucks 🙁 but its what i've got for your unique situation at the moment. Goodluck! :S

Thank you for your help . It can solve part of the problem . Just like the canon . :clap: Is this the temporary solution or the final solution ?

And the others are not solved :

1.Not all of Weapons like the canon . For example , the AK-47 , I want it in front of the character body and behind the right arm . So , it is impossible to create a single skeleton with the right arm . Even the whip weapon , I want it behind the character in some frames and in front of the character in other frames .

Is this can be solved in the future ?

powerboy wrote
Mitch wrote

I know it sucks 🙁 but its what i've got for your unique situation at the moment. Goodluck! :S

Thank you for your help . It can solve part of the problem . Just like the canon . :clap: Is this the temporary solution or the final solution ?

And the others are not solved :

1.Not all of Weapons like the canon . For example , the AK-47 , I want it in front of the character body and behind the right arm . So , it is impossible to create a single skeleton with the right arm . Even the whip weapon , I want it behind the character in some frames and in front of the character in other frames .

Is this can be solved in the future ?

1.Not all of Weapons like the canon . For example , the AK-47 , I want it in front of the character body and behind the right arm . So , it is impossible to create a single skeleton with the right arm . Even the whip weapon , I want it behind the character in some frames and in front of the character in other frames .

This can be solved with the same solution. rename "RightArm" slot to "*RightArm" then set its Sorting Order to something higher than the Whip's Sorting Order in Unity.