Monogame and Spine

Hello, to start sorry for my language
I am french. I would like to import spine json files to monogame.
It’s pretty easy you would tell me because Spine already has libs to do it.

But I would like to have the possibility to change the textures of the animations. For example that my character changes his sword for a pickaxe. Someone will have an example or a solution. I am not strong enough in programming or experience to create my own lib.

Thank you Steph

Once you implement the spine runtime Esoteric has published, you can easily load and replace the texture components with your own.

I’m not sure you want to do that though. The best way may be for your artists to create “skins” in Spine. You can then set that skin in code.

Alternatively, your artist can create different animations and or can play them based on what weapon is active.

This is one where almost everything you need has been created for you and you can walk through the examples.

Thank you for your reply. How do I change the components? When I export the animation to json I directly have a sprite sheet. With all the textures of animation. If for example I want to change the clothes with all the weapons. It will do a lot of possibilities. I can’t imagine the number of textures to have. Isn’t it possible to just change a texture of a bone?
Thank you Steph!

So if you look in XnaTextureLoader.cs you’ll see where it loads and stores the Texture2D reference using MonoGame for spine.

You could replace this with a different texture you yourself have loaded manually in Monogame using Content.Load.

However, I wouldn’t do it that way. I’d design it to swap skins/animations in Spine itself and then just bake the whole thing into a single texture atlas. Then switch the skin in code.

Spine.Skeleton.SetSkin(string skinName)

Okay. Thank you so much. I didn’t know that we could attach several textures and then change it as we wish. I’ll look in the Spine documentation.I would come back if I have more questions. Thank you for your time.

I couldn’t figure out how to use any images that aren’t in the spine export png’s and atlas so I use the libgdx texture packer to replace the .atlas and .png files and then you can swap them out in code. This uses an older version of the spine libraries so I’m not sure if it still works but it should be similar.

  1. Make sure you have Java installed.
  2. Put all the raw spine images (not the spine exported images) AND the images you will swap in into a folder together.
  3. Download libgdx texpacker.jar and put it into the folder.
  4. Add a new file texpacker.bat to the folder and put:

java -jar texpacker.jar .
cmd /k

  1. Add a new file pack.json to the folder and put:

{
useIndexes:false
}

  1. Now that you have a folder with these three files and all the images you will want in the spine double click on texpacker.bat and wait for it to complete.
  2. In your game replace the spine export .atlas and .png files with the ones you generated, the game should be able to load the images and work exactly as it did before.
  3. Here’s the function I made for swapping out the textures
internal void SetAttachmentTexture(int slotIndex, string attachmentName, string attachmentTexture, bool mirror = false)
{
    Spine.Atlas textureAtlas = ContentManagement.ContentLoader.GetSpine("Spine/player").Atlas;
    Spine.RegionAttachment attachment = (Spine.RegionAttachment)SpineSkeleton.GetAttachment(slotIndex, attachmentName);

    // Change the texture region associated to the current attachment
    // Inspired from AtlasAttachmentLoader.cs:NewAttachment
    Spine.AtlasRegion region = textureAtlas.FindRegion(attachmentTexture.Replace("\\", "/"));
    attachment.RendererObject = region;

    if(!mirror)
    {
        attachment.SetUVs(region.u, region.v, region.u2, region.v2, region.rotate);
    }
    else
    {
        attachment.SetUVs(region.u2, region.v, region.u, region.v2, region.rotate);
    }

    attachment.RegionOffsetX = region.offsetX;
    attachment.RegionOffsetY = region.offsetY;
    attachment.RegionWidth = region.width;
    attachment.RegionHeight = region.height;
    attachment.RegionOriginalWidth = region.originalWidth;
    attachment.RegionOriginalHeight = region.originalHeight;

    attachment.Height = attachment.RegionOriginalHeight;
    attachment.Width = attachment.RegionOriginalWidth;
        
    attachment.UpdateOffset();
}

which I call like this:
SetAttachmentTexture(skeleton.FindSlotIndex("hammer"), "hammer", "hammer/" + SwungWeaponComponent.TextureName);