Search Unity

2d sprite sheet avatar dressing system

Discussion in '2D' started by IntDev, Apr 22, 2015.

  1. IntDev

    IntDev

    Joined:
    Jan 14, 2013
    Posts:
    152
    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:

    chrono.png
    And this is for the cloth:
    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?
     
  2. GarBenjamin

    GarBenjamin

    Joined:
    Dec 26, 2013
    Posts:
    7,441
    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.
     
  3. rakkarage

    rakkarage

    Joined:
    Feb 3, 2014
    Posts:
    683
  4. IntDev

    IntDev

    Joined:
    Jan 14, 2013
    Posts:
    152
    But there are many types of clothes in many sheets. I can't change these sprites without making new animations.
     
  5. TomasJ

    TomasJ

    Joined:
    Sep 26, 2010
    Posts:
    256
  6. IntDev

    IntDev

    Joined:
    Jan 14, 2013
    Posts:
    152
    My characters are not splited in parts. Each one is only a sprite.

    An animation is set up like this:

    Untitled-1.png

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

    Wombat85

    Joined:
    Mar 27, 2015
    Posts:
    10
    Could you just layer the new sprite over the prexisiting one?
     
  8. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,790
    Split them apart and use bones. Swap components on each bone at run-time.
    And use layers as Wombat85 suggested.
     
  9. IntDev

    IntDev

    Joined:
    Jan 14, 2013
    Posts:
    152
    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.

    Code (CSharp):
    1. public class SpriteSheetAnimator : MonoBehaviour
    2. {
    3.     public Sprite m_Sprite; // property that is animated using Animator
    4.  
    5.     public Vector3 m_Scale = new Vector3(1f, 1f, 1f); // handles flip; Animator too.
    6.  
    7.     internal Dictionary<string, Sprite> m_BaseSpriteReference;
    8.  
    9.     SpriteSheet[] m_Sheets;
    10.  
    11.     void Awake ()
    12.     {
    13.         m_Sheets = GetComponentsInChildren<SpriteSheet>();
    14.  
    15.         m_BaseSpriteReference = new Dictionary<string, Sprite>();
    16.         foreach (var sprite in Resources.LoadAll<Sprite>("avatar1"))
    17.             m_BaseSpriteReference.Add(sprite.name, sprite);
    18.     }
    19.  
    20.     void LateUpdate ()
    21.     {
    22.         foreach (var sheet in m_Sheets)
    23.         {
    24.             sheet.m_Renderer.sprite = sheet.m_Sprites[m_Sprite];
    25.             sheet.transform.localScale = m_Scale;
    26.         }
    27.     }
    28. }
    Code (CSharp):
    1. public class SpriteSheet : MonoBehaviour
    2. {
    3.     public string m_SheetName;
    4.  
    5.     internal SpriteRenderer m_Renderer;
    6.  
    7.     internal Dictionary<Sprite, Sprite> m_Sprites;
    8.  
    9.     void Start ()
    10.     {
    11.         m_Renderer = GetComponent<SpriteRenderer>();
    12.  
    13.         m_Sprites = new Dictionary<Sprite, Sprite>();
    14.         var m_SheetAnimator = GetComponentInParent<SpriteSheetAnimator>();
    15.         foreach (var sprite in Resources.LoadAll<Sprite>(m_SheetName))
    16.             m_Sprites.Add(m_SheetAnimator.m_BaseSpriteReference[sprite.name], sprite);
    17.     }
    18. }
    Untitled-1.png Untitled-2.png
     
    Last edited: Apr 28, 2015
  10. theANMATOR2b

    theANMATOR2b

    Joined:
    Jul 12, 2014
    Posts:
    7,790
    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.
     
  11. IntDev

    IntDev

    Joined:
    Jan 14, 2013
    Posts:
    152
    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
     
    Last edited: Apr 29, 2015
    theANMATOR2b likes this.