• Editor
  • mix and match skin attachments

Related Discussions
...

This is a late reply, but I ended up doing someything like this and it works like a charm:

private var skins:Array = new Array("Gear_1", "Gear_2", "Gear_3");

public function equip(gear:Gear):void {
	setSkin("Gear_1");
	var skin:Skin = new Skin("my_skin");
	skeleton.skeleton.setToSetupPose();
	
// helmet
setSkin(skins[gear.helmet]);
attach2skin(skin, "<slot name>", "<skin attachment name>");
...
attach2skin(skin, "<slot name>", "<skin attachment name>");

// chest
setSkin(skins[gear.chest]);
attach2skin(skin, "<slot name>", "<skin attachment name>");
...
attach2skin(skin, "<slot name>", "<skin attachment name>");

// yada, yada...repeat for each equpiment
...
...

skeletonData.addSkin(skin);
skeleton.skeleton.skin = skin;
skeleton.skeleton.setToSetupPose();

}

private function attach2skin(skin:Skin, slotName:String, attachmentName:String):void {
	var id:int = skeleton.skeleton.findSlotIndex(slotName);
	var attachment:Attachment = skeleton.skeleton.getAttachmentForSlotIndex(id, attachmentName);
	if (attachment != null) {
		skin.addAttachment(id, attachmentName, attachment);
	}
}

private function setSkin(skinName:String):void {
	skeleton.skeleton.skinName = skinName;
	skeleton.skeleton.setToSetupPose();
}
8달 후

Sorry for necroing. I've been looking up how to do the mix-and-match thing.

Where can I find the official word on how to do this?

In the context of something like item swaps. Or generalizing an NPC skeleton that has mixed and matched hair, eyes, clothes, etc.

Does this mean that it will look totally messed up and kinda unanimatable in the Editor because a skin for just a swappable sword or swappable eyes won't have anything in the skin placeholders for the other swappable things?

If you have a skin per item, yes it may be annoying to animate since the editor currently only allows a single skin to be visible at once.

I think I kinda got it.
https://dl.dropboxusercontent.com/u/567 ... htest.html

Speaking in the context of a New-Skin-From-Scratch whenever you need a new combination of parts:
I've found it's a bit cleaner in the editor and in code if you just put all the necessary attachments under the slot as siblings of the skin placeholders.

The reason being:
In code, you can find them easily through Skeleton.GetAttachment(int slotIndex, string attachmentName) for when you need to construct a new skin using them and their correct alignments.
In the editor, you can see them and test them without stumbling on the one-skin limitation.

While animating, I used skin placeholders so correct data would be in the Animation objects.
And I had to put attachments in those skin placeholders so I could see what I was animating.
So that I could have attachments in them, I duplicated one attachment (out of the many possible attachments) into each skin placeholder that needed one.

This is so ghetto.
Here's some pooped-out C# code:

	void RandomSkinSwap() {
		// WARNING: this orphans any old skins that may have existed,
		// or creates many new Skin objects if called often.
		// A Skin object is mostly just a named wrapper
		// for a Dictionary<KeyValuePair<int, String>, Attachment>

	newSkin = new Spine.Skin("temp");
	string eyesOpenString = GetRandomStringFrom(openEyesStrings);
	string eyesClosedString = GetRandomStringFrom(closedEyesStrings);
	string mouthString = GetRandomStringFrom(mouthStrings);

	newSkin.AddAttachment(eyeSlotIndex, "eyesopen", skeleton.GetAttachment(eyeSlotIndex, eyesOpenString ) ) ;
	newSkin.AddAttachment(eyeSlotIndex, "eyesclosed", skeleton.GetAttachment(eyeSlotIndex, eyesClosedString ) ) ;
	newSkin.AddAttachment(mouthSlotIndex, "mouth", skeleton.GetAttachment(mouthSlotIndex, mouthString ) ) ;
	skeleton.SetSkin(newSkin);

	skeleton.SetSlotsToSetupPose();
}

[EDIT]
In light of this, I want to do a PR for the C# runtime's Skin.cs.

		/// <summary>
		/// This replaces the attachment of a given slotIndex and name with a new attachment.
		/// If one was not previously assigned for the given slotIndex and name, this functions similar to AddAttachment.
		/// </summary>
		public void ReplaceAttachment (int slotIndex, String name, Attachment newAttachment) {
			if (newAttachment == null) throw new ArgumentNullException("attachment cannot be null.");
			attachments[new KeyValuePair<int, String>(slotIndex, name)] = newAttachment;
		}

Think it's okay? Does it fit into what the other runtimes would do? From a semantic perspective, I'm not sure about replacing AddAttachment itself with this logic. Dictionary.Add functions as a non-overwriting add which throws an exception if you try to add an entry with a key that's already in the Dictionary. This ReplaceAttachment method (which uses the [] accessor) is safe to call so it replaces if the key already exists and adds if it doesn't.

Yeah the workflow needs some work, sorry. 🙁 Will get to it in time!

Skin#addAttachment should overwrite an existing attachment. I don't think we need a separate method for it. C# Dictionary sucks I guess. :p

Ah, alright then!
If addAttachment should be able to replace existing attachments, I'll make a PR that replaces AddAttachment's Dictionary.Add with this Dictionary[] assignment.

That'll make it behave as you described.

attachments[new KeyValuePair<int, String>(slotIndex, name)] = newAttachment;
8달 후

hello, I want to use mix and match skin and I try to read you introduction but I'm so dumb. Could you show me how to setup skin in editor and how to coding it in corona? step by step or video please.

Thank you for advice

Please see the documentation for how to setup skins. For Corona, have you looked at the example that comes with it?

I mean how to setup skin for mix and match attachments as this topic and yes I can do normal skin system but I can't figure out when I try to use more than one skin. etc I use corona and I want to change 2 armor "red armor" and "black armor" with 2 weapon "sword" and "spear" as "red armor" + "sword" or "black armor" + "spear".I try to read your introduction mix and match skin for do this but I'm so dumb. can't understand. Could you show me how to setup skin in editor and how to coding it in corona? step by step or video please.


bump

local skin1 = skeleton.data:findSkin("first skin name")
local skin2 = skeleton.data:findSkin("second skin name")
local combinedSkin = Skin.new("new skin name")
for k,v in pairs(skin1.attachments) do
    local slotIndex = v[1]
    local attachmentName = v[2];
    local attachment = v[3]
    combinedSkin:addAttachment(slotIndex, attachmentName, attachment)
end
for k,v in pairs(skin2.attachments) do
    local slotIndex = v[1]
    local attachmentName = v[2]
    local attachment = v[3]
    combinedSkin:addAttachment(slotIndex, attachmentName, attachment)
end
skeleton:setSkin(combinedSkin)

Code written but not tested. This should combine 2 skins into 1.

Thank you very much, now I think I understand your example code but now I have question about how to setup mix and match skin in Spine Editor. Can you explain step by step with an example please.

Thank you in advance.

There's nothing to it beyond the basics you find in the Spine user guide. Create two skins with only the attachments you want, then combine them at runtime. Eg, a "black armor" skin would have all the attachments for black armor, a "red armor" skin would have all the attachments for red armor. You could also have a "light" and "dark" skin that changes the flesh color. Now you can combine these at runtime, eg "red armor + light", "black armor + light", "red armor + dark", etc.