spine-spritekit
spine-spritekit copied to clipboard
Drawing order follows bone declaration order in .json
After much trial and error, it seems that the drawing order for the SKSpriteNodes follows the order that the skeleton's bones are defined in the .json file (rather than any draw order defined in Spine, or the .atlas file). Is this deliberate, and/or the result of technical limitations working with Sprite Kit?
I don't know if it's considered rude to redirect like this, but I have developed a different third party runtime for Spine with SpriteKit that SHOULD support the initial draw order (keyframing isn't supported, however). You can view my project here: https://github.com/mredig/SGG_SKSpineImport
For what it's worth, this runtime is built off of the official ObjC runtime from Spine, whereas mine is more of a reverse engineering of it. I'm not sure which would technically be superior.
@michael thanks for posting it. It's not rude at all
@massivepenguin the JSON file is the only source draw order info comes and tried implement it (not the order of bones construction ) that could be not perfect or the JSON export from spine might not be complete
I'll check the implementation again. Maybe you can share the JSON/atlas files not rendered in the correct draw order?
@simonkim I've created a new Scene in the test project, added an option to the UISegmentedControl, and included the following .json file:
{
"bones": [
{ "name": "root" },
{ "name": "body", "parent": "root", "length": 68.96, "x": 17.5, "y": -64, "rotation": 106.65 },
{ "name": "head", "parent": "root", "length": 79.76, "x": 2.5, "y": -2, "rotation": 82.11 },
{ "name": "leg", "parent": "root", "length": 46.32, "x": 15.5, "y": -82, "rotation": -122.52 },
{ "name": "upper arm", "parent": "root", "length": 44.91, "x": -11.49, "y": -11.99, "rotation": -78.29 },
{ "name": "bone3", "parent": "upper arm", "length": 19.23, "x": 45.89, "y": -0.31, "rotation": 15.82 },
{ "name": "bone5", "parent": "leg", "length": 43.1, "x": 46.39, "y": 3.48, "rotation": 28.51 },
{ "name": "bone6", "parent": "bone5", "length": 35.99, "x": 44.1, "y": 0.06, "rotation": 93.63 }
],
"slots": [
{ "name": "foot", "bone": "bone6", "attachment": "foot" },
{ "name": "lower leg", "bone": "bone5", "attachment": "lower leg" },
{ "name": "upper leg", "bone": "leg", "attachment": "upper leg" },
{ "name": "head", "bone": "head", "attachment": "head" },
{ "name": "eye", "bone": "head", "attachment": "eye" },
{ "name": "hair", "bone": "head", "attachment": "hair" },
{ "name": "torso", "bone": "body", "attachment": "torso" },
{ "name": "upper arm", "bone": "upper arm", "attachment": "upper arm" },
{ "name": "lower arm", "bone": "bone3", "attachment": "lower arm" },
{ "name": "palm", "bone": "bone3", "attachment": "palm" }
],
"skins": {
"default": {
"eye": {
"eye": { "x": 35.47, "y": -37.49, "rotation": -80.65, "width": 20, "height": 19 }
},
"foot": {
"foot": { "x": 8.96, "y": 5.05, "rotation": 0.38, "width": 72, "height": 42 }
},
"hair": {
"hair": { "x": 69.65, "y": -14.59, "rotation": -82.11, "width": 113, "height": 80 }
},
"head": {
"head": { "x": 50.83, "y": -17.19, "rotation": -82.11, "width": 95, "height": 103 }
},
"lower arm": {
"lower arm": { "x": 5.82, "y": 0.34, "rotation": 62.46, "width": 22, "height": 20 }
},
"lower leg": {
"lower leg": { "x": 4.98, "y": 0.34, "rotation": 94.01, "width": 39, "height": 50 }
},
"palm": {
"palm": { "x": 23.2, "y": -3.07, "rotation": 62.46, "width": 32, "height": 33 }
},
"torso": {
"torso": { "x": 33.32, "y": 6.72, "rotation": -106.65, "width": 57, "height": 87 }
},
"upper arm": {
"upper arm": { "x": 17.45, "y": 0.46, "rotation": 78.29, "width": 40, "height": 56 }
},
"upper leg": {
"upper leg": { "x": 17.33, "y": -6.73, "rotation": 122.52, "width": 44, "height": 53 }
}
}
},
"animations": {
"idle": {
"bones": {
"body": {
"rotate": [
{ "time": 0, "angle": 0, "curve": "stepped" },
{ "time": 2, "angle": 0 }
],
"translate": [
{ "time": 0, "x": 0, "y": 0, "curve": "stepped" },
{ "time": 2, "x": 0, "y": 0 }
],
"scale": [
{ "time": 0, "x": 1, "y": 1 },
{ "time": 1, "x": 1.067, "y": 1.207 },
{ "time": 2, "x": 1, "y": 1 }
]
},
"upper arm": {
"rotate": [
{ "time": 0, "angle": 0, "curve": "stepped" },
{ "time": 1, "angle": 0, "curve": "stepped" },
{ "time": 2, "angle": 0 }
],
"translate": [
{ "time": 0, "x": 0, "y": 0 },
{ "time": 1, "x": -7, "y": 9.99 },
{ "time": 2, "x": 0, "y": 0 }
],
"scale": [
{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
{ "time": 1, "x": 1, "y": 1, "curve": "stepped" },
{ "time": 2, "x": 1, "y": 1 }
]
},
"head": {
"rotate": [
{ "time": 0, "angle": 0, "curve": "stepped" },
{ "time": 1, "angle": 0, "curve": "stepped" },
{ "time": 2, "angle": 0 }
],
"translate": [
{ "time": 0, "x": 0, "y": 0 },
{ "time": 1, "x": -1.68, "y": 4.26 },
{ "time": 2, "x": 0, "y": 0 }
],
"scale": [
{ "time": 0, "x": 1, "y": 1, "curve": "stepped" },
{ "time": 1, "x": 1, "y": 1, "curve": "stepped" },
{ "time": 2, "x": 1, "y": 1 }
]
},
"bone3": {
"rotate": [
{ "time": 0, "angle": 0 }
],
"translate": [
{ "time": 0, "x": 0, "y": 0 }
],
"scale": [
{ "time": 0, "x": 1, "y": 1 }
]
}
}
}
}
}
This draws the nodes in the order that the bones are declared, meaning the head and leg appear over the top of the body when in Spine they appear underneath (as intended). Switching the order of the bones to the following:
bones": [
{ "name": "root" },
{ "name": "leg", "parent": "root", "length": 46.32, "x": 15.5, "y": -82, "rotation": -122.52 },
{ "name": "bone5", "parent": "leg", "length": 43.1, "x": 46.39, "y": 3.48, "rotation": 28.51 },
{ "name": "head", "parent": "root", "length": 79.76, "x": 2.5, "y": -2, "rotation": 82.11 },
{ "name": "body", "parent": "root", "length": 68.96, "x": 17.5, "y": -64, "rotation": 106.65 },
{ "name": "upper arm", "parent": "root", "length": 44.91, "x": -11.49, "y": -11.99, "rotation": -78.29 },
{ "name": "bone3", "parent": "upper arm", "length": 19.23, "x": 45.89, "y": -0.31, "rotation": 15.82 },
{ "name": "bone6", "parent": "bone5", "length": 35.99, "x": 44.1, "y": 0.06, "rotation": 93.63 }
]
...draws the nodes in the intended order.
Spine doesn't appear to let you reorder the bones in the interface, and I can't see any settings to output the bone data in relation to its index.
It's not a huge issue as I can always reorder them after Spine exports them, but it would be nice if the SKNodes took some z-position cues from the Spine indexes (which don't appear to export correctly either; something I need to contact esoteric about).
EDIT: it looks like the 'slots' array is exported in the correct draw order. Is there any way to use that to define the order the SKNodes are created?
I need some time to find where is not correctly done. (sorry that i've been away from this project for a while)
In the mean time, if you can read code, search for 'drawOrderIndex' in the source code: https://github.com/simonkim/spine-spritekit/search?q=drawOrderIndex&ref=cmdform&type=Code
these a few lines of code are to give zPosition to each SKNode of corresponding bone according to the draw order (defined in slots).