• Unity
  • Replacing attachment image runtime from persistent Data Pat

I have a spine character. You can see that green character in attachment is the default character. Now I want to replace some of its green images with blue images to make it a totally different character.
I want to download this images over the internet and then apply it to the character runtime. Because of this reason we can not use skins.

Currently, Character has green feet. I want to replace it with the blue foot image. Size of both the image is exactly same. But when I replace the blue foot, it cut from the side. You can see that in the third image.

here's my code for it,


private string[] slotKeys = {  "head", "head_02", "foot", "foot2", "eye", "eye2" };

//[SerializeField] [SpineAttachment(currentSkinOnly = true, slotField = "slotKey")]
private string[] attachments = { "head", "head_02", "foot", "foot", "eye", "eye" };

private bool[] copyFromPrevious = { false, false, false, true, false, true };

private string[] imagesNames = { "blockhead_parts_blue_headA.png", "blockhead_parts_blue_headB.png", "blockhead_parts_blue_foot.png", "blockhead_parts_blue_foot.png", "blockhead_parts_blue_eyeball.png", "blockhead_parts_blue_eyeball.png" };

private Skin[] skins;
IEnumerator Start()
{
    skeletonAnimation = GetComponent<SkeletonAnimation>();
    skeletonData = skeletonAnimation.skeleton.Data;
    m_SourceMaterial = GetComponent<MeshRenderer>().material;
    skins = new Skin[slotKeys.Length];
    Skin l_TemplateSkin = skeletonData.FindSkin("default");
    yield return null;

Attachment l_PreviousAttachment = null;

for (int i = 0; i < slotKeys.Length; i++)
{
    string imageName = imagesNames[i];
    string slotKey = slotKeys[i];
    string attachment = attachments[i];

    m_Sprite = LoadImage(imageName);

    Skin l_NewSkin = new Skin("test" + i.ToString());
    int l_SlotIndex = skeletonData.FindSlotIndex(slotKey);
    Attachment l_AttachmentTemplate = l_TemplateSkin.GetAttachment(l_SlotIndex, attachment);
    Attachment l_NewAttachment = null;
    if (copyFromPrevious[i])
    {
        l_NewAttachment = l_AttachmentTemplate;
        l_NewAttachment.SetRegion(l_PreviousAttachment.GetRegion());
    }
    else {
        l_NewAttachment = l_AttachmentTemplate.GetRemappedClone(m_Sprite, m_SourceMaterial);
        l_PreviousAttachment = l_NewAttachment;
    }

    l_NewSkin.SetAttachment(l_SlotIndex, attachment, l_NewAttachment);
    skins[i] = l_NewSkin;
}

Skin repackedSkin = new Skin("Repacked Skin");
foreach (Skin skin in skeletonData.Skins)
{
    repackedSkin.AddSkin(skin);
}
for (int i = 0; i < skins.Length; i++)
{
    repackedSkin.AddSkin(skins[i]);
}

Material runtimeMaterial;
Texture2D runtimeAtlas;
repackedSkin = repackedSkin.GetRepackedSkin("Repacked Skin", m_SourceMaterial, out runtimeMaterial, out runtimeAtlas);

skeletonAnimation.Skeleton.Skin = repackedSkin;
skeletonAnimation.Skeleton.SetSlotsToSetupPose();
}


Related Discussions
...

If you want to use a loaded Sprite you should still use l_AttachmentTemplate.GetRemappedClone(m_Sprite, m_SourceMaterial), if the region is the same you can set the optional parameter useOriginalRegionSize : true which defaults to false when not specified:
https://github.com/EsotericSoftware/spine-runtimes/blob/3.8/spine-unity/Assets/Spine/Runtime/spine-unity/Utility/AttachmentCloneExtensions.cs#L89-L90

I changed that but it ended up adding multiple images in the sprite sheet. That is not actually the problem. Problem is that after I change sprites runtime then it get cuts from the sides. Dimensions of both the sprites are same. But somehow some sprites are scaled up and some are scaled down a bit.

I am not able to figure out why. I can also send you test project if you want.

We are sorry for the troubles! Let's please continue the discussion over at this thread since it looks like the same problem:
Replace body part via code