Abelius

Hi there,

So, after months on the Editor, it's time to return to Unity and put a Mix'n'Match system in place, for my customizable models.

I've learned there can only be one active skin on a skeleton, so the actual "additive skins" deal consists of generating a collection of skins that "overwrite" each other sequentially and activate it at the end. That's fine.

It also seems, from what I'm reading on the old forum threads, that the default way of doing this is by returning all slots to setup pose each time we do the above.

However, I'm wondering if there is some way to just add a skin to the already enabled attachments of a skeleton, instead of needing to generate a brand new combined skin every single time.

The pseudocode would be like this...:

1.- Get SkeletonAnimation object
2.- "Read" all active attachments into var skin1
3.- Append skin1 and skin2 (skin to add) into one combined skin
4.- Set combined skin

I guess you'll probably ask me why I would want to do this if the game is actually supposed to know the graphical setup of my characters at all times, and I'm inclined to admit that should be the case, yes.

However, I'd feel much more at ease knowing I have multiple ways to reach the same goal. :think:

Is this doable?

Thanks!
Аватара пользователя
Abelius
  • Сообщения: 170

Nate

A skeleton has a "skin" and a "default skin". Skeleton getAttachment looks for attachments in the skin first, then the default skin, and that is what eg animations use to find an attachment when attachment keys change attachments. Note the skin is stored per Skeleton while the default skin is stored per SkeletonData.

You can just get the skeleton's skin (which may be null) and manipulate it by adding/removing attachments. In your example, if the skeleton has skin1 already, you can just get the Skeleton skin and use Skin addSkin to add skin2 to it. You'd only need to create a new skin if you don't want to muck up skin1 because eg maybe you'll use it later, or maybe other skeletons are using it.

By "enabled" attachments do you mean currently attached attachments? Or do you mean all the attachments in the current skin, whether attached or not?

When you set a new skin (or manipulate the skin already set on the skeleton), the Spine Runtimes can't know what you want to do with attaching or detaching attachments. Do you want to detach all the attachments? Detach all attachments from the old skin? Set attachments from the new skin? Which ones? There can be many attachments in the skin for each slot.

The default behavior is:
Attachments from the new skin are attached if the corresponding attachment from the old skin was attached. If there was no old skin, each slot's setup mode attachment is attached from the new skin.
This is done because it's safe and pretty often what is wanted. If it's not what you want, you'll need to set the attachments as you like. One way to do that is to use Skeleton setSlotsToSetupPose. Another is to look at your game's state and set the appropriate attachments, eg for the equipped items. Additionally you may want to apply an animation, in case that sets other attachments.

You can iterate the slots using Skeleton slots and Slot attachment will tell you what attachment is currently attached (if any). However, you won't know which skin placeholder name that attachment is for (if any).

You can iterate the attachments in a skin using Skin getAttachments. Hmm, the API reference doesn't show the correct parameters. Edit: ah this is already fixed in the v4 beta API reference, which also shows some additional methods that are actually in 3.8: addSkin, copySkin, and clear.

Anyway, getAttachments takes (int slotIndex, List<SkinEntry> attachments) and gives you all the attachments for a particular slot. Each SkinEntry gives you the name in the skin (which is the placeholder name as seen in the Spine editor) and the actual attachment for that name (which of course may have a different name). You can check if the attachment is attached, eg using this pseudo code:
var entries = new List<SkinEntry>();
for (Slot slot : skeleton.slots) {
entries.clear();
skeleton.skin.getAttachments(slot.index, entries);
for (SkinEntry entry : entries) {
if (slot.attachment == entry.attachment) {
// Here we know entry.attachment is attached.
// The name in the skin is: entry.name
}
}
}
You may also want to do this for the default skin, depending on what you need.
Аватара пользователя
Nate

Nate
  • Сообщения: 9861

Abelius

Hi Nate,

Many thanks for another comprehensive explanation. :p

I got it working as I wanted, using AddSkin.
Nate писал(а):By "enabled" attachments do you mean currently attached attachments? Or do you mean all the attachments in the current skin, whether attached or not?
Currently attached. I guess I didn't use the correct terms when writing the thread. I just want to change what it is under the skin placeholders in each slot.

I also forgot to mention I'm modifying a very old PlayMaker action, because I "code" like that, lol. So, maybe in some days or weeks, I'll ask you if the action script looks good, performance-wise.

Thanks!
Аватара пользователя
Abelius
  • Сообщения: 170


Вернуться в Unity