Search Unity

Changing Animation Sprites

Discussion in '2D' started by Danimita92, Nov 26, 2013.

  1. Danimita92

    Danimita92

    Joined:
    Jan 25, 2010
    Posts:
    22
    Hi everyone!

    I have a quick question regarding sprite animation in Unity's new 2D features.

    Say I have a character's sprite sheet with different animations (idle, walk, jump, etc.) and I have a similar sprite sheet (same character, different armor) with the same ammount of frames and animations. The only thing that changes is the texture.

    I have seen that to make 2D animations you have to drag the sprite's frames into the animation timeline, but what if I have loads of different characters with the same animations? Would I have to create new animations in the editor for each one of the different versions of the same character?

    Thanks for your time!
     
    rakkarage likes this.
  2. Danimita92

    Danimita92

    Joined:
    Jan 25, 2010
    Posts:
    22
    Nobody knows? Is it impossible to do this in Unity's sprites system?

    How about with animation events? Would it be expensive performance-wise to change sprites via animation events and code?
     
  3. guykogus

    guykogus

    Joined:
    Aug 12, 2013
    Posts:
    5
    You could programmatically create the animations by adding curves and setting the values to the appropriately named sprites, loading each texture one at a time. Probably not a good way to go about doing this.

    If you're redrawing each animation depending on the character's armour, you may then want to have a separate animation per armour, and trigger those animations based on the current armour.

    Hope that helps :\
     
  4. keely

    keely

    Joined:
    Sep 9, 2010
    Posts:
    966
    We don't offer nice built-in workflow in 4.3 for this.

    There are different ways to achieve this "manually", but it requires some scripting on your part.

    We are researching how to make a nice built-in workflow, but I can't really say anything more specific at this point.
     
  5. Danimita92

    Danimita92

    Joined:
    Jan 25, 2010
    Posts:
    22
    Oh, well. Thanks for the reply.

    To achieve it manually, what would be the most efficient way? With animation events that change sprites for others in an array, perhaps?
     
  6. cpavanelli

    cpavanelli

    Joined:
    Apr 11, 2013
    Posts:
    6
    Hi, I know you posted a while ago, but I will share what I have done when I faced the same problem.

    I was going to use sprite sheets to animate my characters, but in order to my character be customizable, I had to:

    1. slice the character in body parts

    2. Created animations using the parts

    3. On the code (start method), loaded the specific png(sprite) from resources folder and set it to the sprite gameobject. (only in cases that it need to be different, like an armor instead of the regular body).


    Also, I'm not sure this works if your animation is changing sprites (like handClosed to handOpen).
     
  7. Akika

    Akika

    Joined:
    Sep 18, 2013
    Posts:
    2
    Could you please at least give us some ideas about that "scripting on our part".. I have 50+ different characters with 40+ base animations in my game, and it pains me just to think about making 2000+ animations, 50+ animator graphs. I will appreciate any help here. If a full scale tutorial is time-costly, could you please just point out some basics. Thanks in advance.
     
    eaglethrust and rakkarage like this.
  8. jjarmis

    jjarmis

    Joined:
    Feb 25, 2014
    Posts:
    2
    I have the same need and have yet to figure out a good workaround. If anyone has figured this out without making thousands of animators, I would love to see some sample code.

    - Thank you -
     
    rakkarage likes this.
  9. Loius

    Loius

    Joined:
    Aug 16, 2012
    Posts:
    546
  10. jjarmis

    jjarmis

    Joined:
    Feb 25, 2014
    Posts:
    2
    That looks cool. Two things.

    I cant find it in the asset store.

    From what I've seen in the video, it doesn't solve the original issue. Which is to change from one sprite sheet to another using the same animation files during run time. That way if we have say 500 different sheets with a different character on each, and all the same frames, we only have to setup one animation set instead of 500.
     
  11. Loius

    Loius

    Joined:
    Aug 16, 2012
    Posts:
    546
    It hadn't gotten through Unity's vetting process yet - It's available now, though; more info in this thread.

    The SpriteSheet component actually stores animations (it's completely separate from Mecanim). Once you have a SpriteSheet with its animations set up, you can swap in a new texture in a duplicate object. So you could have, say, a blue enemy, then recolor it and save as a new texture - you could plug that new texture in to populated SpriteSheet and have a working sheet without having to rebuild the animations.

    The sheet does still have to acquire its sprites in the Editor; my code-fu has not found a way to find sprites at runtime yet. But you can make a bunch of duplicate SpriteSheets with different textures. The only thing that's important is that the sprites be in the same order.
     
    Last edited: Mar 1, 2014
  12. Akika

    Akika

    Joined:
    Sep 18, 2013
    Posts:
    2
    Ok, to all people, who want 50+ similar animations of 50+ characters,and want it right now, without waiting some "nice workflows" to come.
    Give up on mecanim. I did. Just used SpriteManager (http://wiki.unity3d.com/index.php?title=SpriteManager). It's free, powerfull and opensource. I've added some stuff, like sharing spritesheet regions and advanced z-ordering, and it became even more sexy. And it took me just one day to rewrite all my animation mechanisms, so that project is alive and kicking.
     
  13. hawken

    hawken

    Joined:
    Aug 22, 2013
    Posts:
    503
    Having same problem, this feature is badly needed for the next version of Unity!
     
  14. v-line

    v-line

    Joined:
    Feb 13, 2013
    Posts:
    10
    I'm going to implement armor in my project.
    The best solution I've got is to create separate objects for each part of a character and make a separate animator for each part.
    If a character changed his helmet, the appropriate object with its own animator should replace the default head object.
    However will take some time to manually create animators.
     
  15. marceloSpiezzi

    marceloSpiezzi

    Joined:
    Nov 12, 2012
    Posts:
    6
    I've been searching a lot about this too, found the answer here (at 20:00)

     
    danrayson and rakkarage like this.
  16. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    6,908
    Correct me if I'm wrong, but it doesn't look like that technique will work on sprite animations.
     
    Menion-Leah likes this.
  17. Yagef

    Yagef

    Joined:
    Jul 2, 2014
    Posts:
    1
    I used this method for my project and it worked perfectly. Very useful lection
     
    Last edited: Jul 2, 2014
  18. zgamesoft

    zgamesoft

    Joined:
    Jun 3, 2013
    Posts:
    1
  19. Most_Incredible

    Most_Incredible

    Joined:
    Jan 25, 2012
    Posts:
    22
    Hi,
    Do we have any better workflow in the latest Unity version on this.Kindly throw some light on this.
    Thanks
     
  20. AlexBM

    AlexBM

    Joined:
    Mar 26, 2015
    Posts:
    16
    I think I found quite simple solution for that. Not super-efficient, but still it may save you a lot of time as it's very easy to implement.

    The main idea is to use current sprite name in animation as a key to lookup in Dictionary of sprites with different skins. In terms of code is something like that

    Code (CSharp):
    1.  
    2. void LateUpdate()
    3. {
    4.  // heavyArmorSkin is a Dictionary with skinned sprites
    5.  BodySprite.sprite = heavyArmorSkin[BodySprite.sprite];
    6. }
    7.  
    So basically, each Update Animator changes a sprite according it's internal state, and you use this sprite name as a key for the actual sprite of your skin and replace it.
     
  21. MerlinsMaster

    MerlinsMaster

    Joined:
    Jan 15, 2015
    Posts:
    28
    Hey, man. Any chance you could show your entire script? It would be great to see it in context.
     
  22. DarkCooker

    DarkCooker

    Joined:
    Jan 7, 2015
    Posts:
    92
    Hi How's the performance in game?
    From profiler, I see the LateUpdate eats up 2% CPU usage and 21.1KB GC alloc.
    Not sure if you have try it in production environment, thank you.
     
  23. churi24

    churi24

    Joined:
    Sep 17, 2013
    Posts:
    78
    Maybe this code could help you.. I don't know if performance in your case is a must, but this work.
    If you name the sprite as Warrior, the substrings will have this form... Warrior_0, Warrior_1, ... , Warrior_n
    so I take the index with this line renderer.sprite.name.Substring(8) and then I replace the sprite. With this you dont need to made separated animations.

    Code (CSharp):
    1. public class ReskinAnimator : MonoBehaviour
    2. {
    3.     public Sprite[] subSprites;
    4.    
    5.     void LateUpdate()
    6.     {
    7.         foreach (var renderer in GetComponentsInChildren<SpriteRenderer>())
    8.         {
    9.             renderer.sprite = subSprites[int.Parse(renderer.sprite.name.Substring(8))];
    10.         }
    11.     }
    12. }
     
    Zelek and Most_Incredible like this.
  24. retry_entry

    retry_entry

    Joined:
    Nov 7, 2016
    Posts:
    1
    Hi guys. Please tell me where I am wrong... Cause I have found a solution and using it to a great success...
    Ramaging through sprites in LateUpdate kinda... Ehm... What is this really?
    I use shader and pick swapped texture with main texture UVs...
    U can check it here - https://github.com/RetryEntry/UnityAnimatorChangeSprite
    Give stars please or tell me why it sucks... :/
     
  25. danrayson

    danrayson

    Joined:
    Mar 3, 2013
    Posts:
    10
    This is exactly the answer, fantastic!! Production env not tested...

    I used this code:

    Code (CSharp):
    1.     private void SetTheCorrectSpriteForThisObject()
    2.     {
    3.         string path = "Graphics/Characters/" + Statistics.Race + "/" + Statistics.Class;
    4.         Sprite[] allSubSprites = Resources.LoadAll<Sprite>(path);
    5.      
    6.  
    7.         overrideSprite = allSubSprites.FirstOrDefault(s => s.name.Equals(SpriteRenderer.sprite.name));
    8.         if (overrideSprite)
    9.         {
    10.             SpriteRenderer.sprite = overrideSprite;
    11.         }
    12.     }
    And made sure I had sprites whos sub-sprites where called the same names, e.g. Idle1, Idle2, etc. That's it
     
  26. GoblinGameWerks

    GoblinGameWerks

    Joined:
    Sep 14, 2019
    Posts:
    4
    So if your new sprite sheet has more sprites like other dangling accessories or an extra arm etc. I don't believe this method will work... or at least I haven't found the workaround yet. In my case i have 5 faces that I need to add to the sprite sheet.

    I animated a very long and complicated sequence, a sprite sheet with 7 sprites which were all connected as bones but without a face on the character and thought I could maybe add the face later (think I got confused by a YT video I watched).

    Well problem is the head moves so much and trying to get the face to stay in the right place while the character is moving is challenging (not impossible) but it seems so inefficient to do it manually like that. I thought for sure there's a better way.

    Copying the transform or "childing" the faces to the sprite game object doesn't work because the animated sprite's transform's rotation never changes, however the head bone rotates and changes position like crazy.

    I wish I would have foreseen this issue and simply included all the faces on top of each other when creating the sprite initially and while creating the bones I could have made each face use the head bone as its sole "influencer" then simply turn the faces on and off from the inspector during the animation this way the faces rotate and follow the head bone regardless where it is in the scene.

    example: character is happily walking smiling then starts to lose balance and begins to stumble so face changes to fearful, regains balance face changes to sigh of relief, then face changes to a more joyful face than at the start.
     
    eaglethrust likes this.