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.