Hi.
I want to mix and match skins with Spine Animation file.(also known as combining skins in runtime, or commonly, Avatar system)
Cocos2d-x version: 3.16
Spine version: 3.6.52 Essential
It is well known that Spine editor’s Skin function is to switch all parts in whole, not to mix and match each parts, combining multiple skins. But some documents mentioned that it is possible in runtime.
This is the page where I get the ideas, written by Unity C#
https://github.com/pharan/spine-unity-docs/blob/master/Mix-and-Match.md
with this info, I want to re-write the code with Cocos2d-x.
first I prepared the data.
I modified “goblns.spine” in the Spine samples like below:
- removed all the skin placeholders except each hands (2 skin place holders for lower layer and upper layer of the right hand and 1 for left hand)
- left hand has two skin attachment: dagger and spear
- right hand has two skin attachment: dagger and shield (top)
- Skins has only one skin: template
then the code:
SceneGame.h and .cpp is the typical HelloWorld scene with some menuItems.
.h
class SceneGame : public cocos2d::Layer
{
...
spine::SkeletonAnimation *mSpine;
}
.cpp
bool SceneGame::init()
{
...
mSpine = spine::SkeletonAnimation::createWithJsonFile("goblins.json", "goblins.atlas");
mSpine->setSkin("template");
mSpine->setPosition(Vec2(320, 100));
mSpine->setAnimation(0, "walk", true);
this->addChild(mSpine);
...
// created some menuitem buttons
}
and this is the actual skin changing code. (callback for button)
It’s actually a re-writing of the unity C# code in the link above.
void SceneGame::Callback_Button(Ref *pSender)
{
spSkeleton *tSkel = mSpine->getSkeleton();
int lhandSlotIndex = spSkeleton_findSlotIndex(tSkel, "left hand item");
int rhandSlotIndex = spSkeleton_findSlotIndex(tSkel, "right hand item");
spAttachment *lDaggerAttachment = spSkeleton_getAttachmentForSlotIndex(tSkel, lhandSlotIndex, "left hand dagger");
spAttachment *rDaggerAttachment = spSkeleton_getAttachmentForSlotIndex(tSkel, rhandSlotIndex, "right hand dagger");
spSkin *newSkin = spSkin_create("newskin");
spSkin_addAttachment(newSkin, lhandSlotIndex, "lf hand dagger", lDaggerAttachment);
spSkin_addAttachment(newSkin, rhandSlotIndex, "rt hand dagger", rDaggerAttachment);
spSkeleton_setSkin(tSkel, newSkin);
spSkeleton_setSlotsToSetupPose(tSkel);
mSpine->update(0);
}
but when I run the scene and pressed the button, this is what I get:
BEFORE:
AFTER:
Fortunately it did not crashed but the hands, where all weapons were supposed to be changed to daggers, were empty.
I am in my witt’s end. Can anyone please help me?