2d sprite sheet avatar dressing system

I have a 2d sprite sheet avatar and I want to put clothes like tshirt, shoes, sunglasses, etc.

Just as example, this is the sprite sheet for the body:

2079857--135895--chrono.png
And this is for the cloth:
2079857--135896--cloth.png
Notice that there are many other items that he can wear at same time.
Notice that there are many animations like walk front, back, side, etc.

What is the best way to do such a dressing system?

Create a complex object meaning instead of a single GameObject for your sprite use multiple GameObjects. These “props” would be children of the main sprite.

But there are many types of clothes in many sheets. I can’t change these sprites without making new animations.

Perhaps this will help 2D Puppet Rigging - Tips Tricks - Unity Engine - Unity Discussions

My characters are not splited in parts. Each one is only a sprite.

An animation is set up like this:

2081983--136080--Untitled-1.png

And I see no way of changing theses sprites without making an animation for each character, even though they are equals.

Could you just layer the new sprite over the prexisiting one?

Split them apart and use bones. Swap components on each bone at run-time.
And use layers as Wombat85 suggested.

Can’t be done using bones. Using layers, will lead to making new animations each time a new item is added, and tons of layers. Unfortunately unity has no good solution to this issue. The best I could make is, I animate my own Sprite property, then I change each child item sprite using the current sprite, in LateUpdate.

public class SpriteSheetAnimator : MonoBehaviour
{
    public Sprite m_Sprite; // property that is animated using Animator

    public Vector3 m_Scale = new Vector3(1f, 1f, 1f); // handles flip; Animator too.

    internal Dictionary<string, Sprite> m_BaseSpriteReference;

    SpriteSheet[] m_Sheets;

    void Awake ()
    {
        m_Sheets = GetComponentsInChildren<SpriteSheet>();
 
        m_BaseSpriteReference = new Dictionary<string, Sprite>();
        foreach (var sprite in Resources.LoadAll<Sprite>("avatar1"))
            m_BaseSpriteReference.Add(sprite.name, sprite);
    }

    void LateUpdate ()
    {
        foreach (var sheet in m_Sheets)
        {
            sheet.m_Renderer.sprite = sheet.m_Sprites[m_Sprite];
            sheet.transform.localScale = m_Scale;
        }
    }
}
public class SpriteSheet : MonoBehaviour
{
    public string m_SheetName;

    internal SpriteRenderer m_Renderer;

    internal Dictionary<Sprite, Sprite> m_Sprites;

    void Start ()
    {
        m_Renderer = GetComponent<SpriteRenderer>();

        m_Sprites = new Dictionary<Sprite, Sprite>();
        var m_SheetAnimator = GetComponentInParent<SpriteSheetAnimator>();
        foreach (var sprite in Resources.LoadAll<Sprite>(m_SheetName))
            m_Sprites.Add(m_SheetAnimator.m_BaseSpriteReference[sprite.name], sprite);
    }
}

2089296--136631--Untitled-1.png 2089296--136632--Untitled-2.png

You are saying it can’t be done with the sprites you are currently using right? Because it can be done with bones, though not easily accomplished with how your sprites have been created.

I agree using layers will result in a heavy lift - but that is one solution that works (though I’d hate it)

Is this child item sprite drawn on top of the base sprite in LateUpdate? Does this work as desired? Underdeveloped left brain restricts me from completely understanding your code.

right.

yes, since each sprite has its own sorting order.

What I did was just synchronize itens&avatar animations based on the current sprite being played, each item sprite is updated according to current sprite defined at the animation, using its own sprite though. I can attach an example project tomorrow if you wish to take a closer look.

PS: I just remind, actually you can download it here: https://bitbucket.org/Unity-Technologies/2ddemos/issue/16/2d-sprite-sheet-avatar-dressing-system

1 Like