Hello, thank you for taking the time to read this and see if you can help me out.
First of all, I just want to say that I'm sort of new to Spine, I've been learning for around a year in my free time and it has been melting my brain (specifically learning how to code with Spine.Unity)
I've been working on a personal project that uses mix and match logic in two different ways; one from the Mix and Match Equip demo scene and one from the Mix and Match Skins demo scene, but I've run into a brick wall that I can't find a way around.
I've been searching through the forums trying to see if other users have tried this, and I've scoured through the API & other materials provided to try to make sure I don't miss an obvious answer. I'm sorry if this is something that is covered somewhere that I missed.
All that out of the way, on to the meat and potatoes of my issue:
I have a Generic Character Animator that I'm working on, the default skin is a nude character. It currently has four skins, the eyes, helmet, body armor and leg armor.
I had the sprite swapping logic working with the Spine Dummy when it didn't have skins, but I learned that skins were the way forwards for equipping gear like this-
and now I have the logic for equipping / unequipping gear working flawlessly; however- I cannot seem to figure out the sprite swap code again now that I have skins involved.
Specifically, the sprite swap code still works for the slots that are on the base skin, but the slots that have been moved to their own skins aren't being referred to properly and I'm having trouble figuring out how they need to be referred to.
When I have the armored slots disabled; the animation will add the skins but the atlas will be messy like this; because the logic to add sprites before the repack is disabled- and if it doesn't have sprites to place in the repack, the repack doesn't work (enabling them causes it to abort as soon as it can't find the slot I ask it to)
I did this for testing purposes, to make sure the part that adds the skins worked at all.
customSkin.AddSkin(skeletonData.FindSkin("Head/Armored"));
customSkin.AddSkin(skeletonData.FindSkin("Torso/Armored"));
customSkin.AddSkin(skeletonData.FindSkin("Legs/Armored"));
customSkin.AddSkin(skeletonData.FindSkin("Eyes/Open"));
When I have the armored slots enabled (Code:
int helmetSlotIndex = skeleton.Data.FindSlot(helmetSlot).Index;
Attachment templateHelmet = templateSkin.GetAttachment(helmetSlotIndex, helmetKey);
Attachment newHelmetAttachment = templateHelmet.GetRemappedClone(helmetSprite, sourceMaterial, pivotShiftsMeshUVCoords: false);
if (newHelmetAttachment != null) customSkin.SetAttachment(helmetSlotIndex, helmetKey, newHelmetAttachment);
); the animation fails to add the sprites to it because I am not calling it in the code properly, and nothing appears to happen to the large dummy. (the smaller dummies remain on the scene to show that the other rigs are still working and that I didn't break the scene)
The error message I get in the console shows me this:
NullReferenceException: Object reference not set to an instance of an object
Spine.Unity.AttachmentTools.AttachmentCloneExtensions.GetRemappedClone (Spine.Attachment o, Spine.AtlasRegion atlasRegion, System.Boolean cloneMeshAsLinked, System.Boolean useOriginalRegionSize, System.Single scale) (at Assets/Spine/Runtime/spine-unity/Utility/AttachmentCloneExtensions.cs:104)
Spine.Unity.AttachmentTools.AttachmentCloneExtensions.GetRemappedClone (Spine.Attachment o, UnityEngine.Sprite sprite, UnityEngine.Material sourceMaterial, System.Boolean premultiplyAlpha, System.Boolean cloneMeshAsLinked, System.Boolean useOriginalRegionSize, System.Boolean pivotShiftsMeshUVCoords, System.Boolean useOriginalRegionScale) (at Assets/Spine/Runtime/spine-unity/Utility/AttachmentCloneExtensions.cs:74)
Spine.Unity.Equipper2.SpriteSwap () (at Assets/Scripts/Equipper2.cs:199)
Spine.Unity.Equipper2+<Start>d__116.MoveNext () (at Assets/Scripts/Equipper2.cs:175)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <be28439f7b014fc38435d198c0640ff7>:0)
Spine.Unity.Equipper2.SpriteSwap () (at Assets/Scripts/Equipper2.cs:199) seems to be the important line, and when I bring up that line of code:
Attachment newHelmetAttachment = templateHelmet.GetRemappedClone(helmetSprite, sourceMaterial, pivotShiftsMeshUVCoords: false);
Thats the line it specifically refers to, which is part of this:
int helmetSlotIndex = skeleton.Data.FindSlot(helmetSlot).Index;
Attachment templateHelmet = templateSkin.GetAttachment(helmetSlotIndex, helmetKey);
Attachment newHelmetAttachment = templateHelmet.GetRemappedClone(helmetSprite, sourceMaterial, pivotShiftsMeshUVCoords: false);
if (newHelmetAttachment != null) customSkin.SetAttachment(helmetSlotIndex, helmetKey, newHelmetAttachment);
The part where I think it is broken is in the helmetKey. When I go in the inspector on the slots that sprite swap currently works on, each of those slots & keys finds its respective option on the inspector.
But when it is for one of the slots that I added to the skins, null is the only field that comes up.
Here is the code for the bare head compared to the armored helmet.
Bare Head
[Header("Bare_Head")]
public Sprite bareHeadSprite;
[SpineSlot] public string bareHeadSlot;
[SpineAttachment(slotField: "bareHeadSlot", skinField: "baseSkinName")] public string bareHeadKey = "Nu_Head";
Armored Head
[Header("Helmet")]
public Sprite helmetSprite;
[SpineSlot] public string helmetSlot;
[SpineAttachment(slotField: "helmetSlot", skinField: "Head/Armored")] public string helmetKey = "Leather_Head";
and I know that the helmetKey is a string that is determined by filenames in Spine, so here are what those respective slots look like in Spine.
This makes me think that the string for the helmetKey (and all of the slots that are on skins) isn't properly set up, but my guesses haven't been working and I'm at a loss.
My goal with this is to be able to equip items and have the sprites that are on each scriptable object/item pass their sprites to the script that is doing the sprite swap so that those sprites will show on the animation.
If you've made it this far, thank you for reading this and taking the time to help me out. If there is any more information I can provide that would make this easier to assist with I'm happy to provide it.
I solved this by making variables for each of the skins and then using those variables in the skinField: portion of the SpineAttachment fields.