Search Unity

Is it better to use sprite swapping or animations?

Discussion in 'Animation' started by adrianrodriguez, Sep 29, 2014.

  1. adrianrodriguez

    adrianrodriguez

    Joined:
    May 29, 2013
    Posts:
    16
    I hope I'm posting this in the right forum, if not I apologize and will not be offended if moved.

    Let's start: I'm making a simple 2D fighting game (or at least before I started I thought it was simple) and I am trying to nail down whether or not it's better to swap my sprite during a keypress or animate the sprite.

    What I want to happen:
    • Either would happen on key press.
    • Either would update the box collider of the gameObject (if that's possible).
    • Either would happen only once.
    I'm trying to keep things simple (My goal is to just have a playable game by the end of the year) before I start to explore more and improve my skill with Unity and C#.

    Right now each character only has a punch, kick, and idle state. So any animation/swap is only one frame long and shouldn't ever loop which is why I thought to use a sprite swap, but I hear it's easier to change the box collider for animations, but I don't ever need it to loop. So I am rather torn on what's the better approach.

    Here's an image of my game btw, (mind you I'm not focusing too much on artwork, just on mechanics as I'm just learning/improving things little by little).



    Thanks ahead of time for any advice or suggestions, been going back on this for a week or so now.
     
  2. GarBenjamin

    GarBenjamin

    Joined:
    Dec 26, 2013
    Posts:
    7,441
    You can always try both approaches and see which works best for you. The collider systems in Unity makes this kind of thing much harder than it should be. It's kind of odd really. Unity seems to make some of the very complex tasks in game development very simple and yet the things that are normally simple (setting up collisions based on animated sprite images) are nearly impossible to do. I don't get that really but imagine it was a lack of sufficient time spent in design and testing.

    I tried the Unity animation system for my first project and while it worked I found it took far more time than just doing the same thing in code. So for my current project I am no longer using Animator or even Legacy animations. It's just so much simpler and faster to code the stuff in my opinion. And then when you add on the colliders needing to be linked to the animation images (sprites in Unity) it is far simpler to do it in code to me anyway.

    I spent a lot of time researching online in the beginning and I think one of the reasons all I ever found were super simple platform games and so forth (and usually the more involved ones had block style characters) is simply due to the fact of how much work it is do this in Unity, if it is even possible.

    There could be some undocumented (or at least obscure) piece I am missing. The bottom line is the colliders should be associated with the Sprites (images) themselves instead of the GameObject. The ideal would be when we slice up a sprite sheet polygon colliders are automatically created and associated with the sprites at that time. That would be the logical way to do it.

    Enough rambling. At any rate feel free to update what you try and how it works for you.
     
  3. adrianrodriguez

    adrianrodriguez

    Joined:
    May 29, 2013
    Posts:
    16
    Garbenjamin thanks for the reply, I was beginning to think this was a lost thread.

    It's funny that you mentioned it could be the reason why there are so many platform games out there. I actually decided today that I was going to instead work on a platform game because I may have bitten off more than I can chew for my first game being a fighter. Even one as simple as this, and while coding the colliders in would more than likely be simpler, for me however it's not since I am new to C#. I might explore this further for future references and future games, but I think I might abandon this specific project and maybe tackle something a little easier for my first game.
     
  4. GarBenjamin

    GarBenjamin

    Joined:
    Dec 26, 2013
    Posts:
    7,441
    Keep your characters kind of like little rectangles and all you'll need is a single box or polygon collider on each.

    Alternately, after thinking about it some more, you can make all of your characters complex objects. Meaning you have a rectangular sprite for the torso and chest area. Another two sprites for the left arm, another two sprites for the right arm, four more for the legs and another for the head. Each would be a child game object attached to the parent character game object. Each would have a single collider on them. Then you can use rotation to animate the character and the collider should rotate too. I think. Maybe. I am guessing this is how they envisioned 2D games being made and never considered a developer might simply have full images for each character's animations.

    That method is viable and actually makes it more efficient to do things like weapon swaps and such but again it is a lot more work that in many cases would not be needed.

    Platform games themselves are not necessarily simple I just meant the games I checked out in videos and web players were always very simple. I think most of them actually had the entire level created as a scene and didn't even use a tile engine.
     
    Last edited: Sep 30, 2014
  5. adrianrodriguez

    adrianrodriguez

    Joined:
    May 29, 2013
    Posts:
    16
    Ah, understood. That approach was actually something I was considering. Designing my characters to be almost geometric and animate individual parts of them with colliders. Thanks for clarifying that for me further though, it makes a lot of sense.
     
  6. GarBenjamin

    GarBenjamin

    Joined:
    Dec 26, 2013
    Posts:
    7,441
    Alright, I am back with more. lol ;)

    Anyway, tonight I spent my two hours of game project time trying different ways of handling this and in the end I came back to the system I came up with last winter.

    I think it really is the easiest way of doing it. Last winter I had the system set up to work with Animator animations. But, like I said, I dropped those this time around. Now, I just use arrays of images (sprites) which is what I am used to using before trying Unity.

    All of this code goes into the script attached to my game objects that need animated polygon colliders.

    This example is for the enemy snakes in my platform game. So this is all in the Enemy Snake Game Object script.

    At the top:
    Code (CSharp):
    1. // Array of images for the snake's animation.
    2. // This is loaded in the Inspector.
    3. public Sprite[] aImages;
    4.  
    5. // Dictionary containing an integer frame (sprite) index
    6. // and the associated polygon collider.
    7. private Dictionary<int, PolygonCollider2D> olFrameColliders;
    8.  
    9. // tracks the current frame
    10. private int curFrame;
    11.  
    12. // tracks the previous frame
    13. private int oldFrame;
    14.  
    15. // a reference to this game object's Sprite Renderer
    16. private SpriteRenderer oSpriteRenderer;

    This code goes into the Awake() method:
    Code (CSharp):
    1.  oSpriteRenderer = this.GetComponent<SpriteRenderer>();
    2.  
    3. // This section creates the colliders for this snake
    4. // First we need to instantiate the Dictionary.
    5. olFrameColliders = new Dictionary<int, PolygonCollider2D>();
    6.  
    7. // loop through each Sprite (image) in our Images array
    8. for(int index = 0; index < aImages.Length; index++)
    9. {
    10.     // switch to the current image we are processing
    11.     oSpriteRenderer.sprite = aImages[index];
    12.  
    13.     // create the polygon collider and add it to the Dictionary
    14.     olFrameColliders.Add(index, gameObject.AddComponent<PolygonCollider2D>());
    15.  
    16.     // disable the collider
    17.     olFrameColliders[index].enabled = false;
    18.  
    19.     // set this as a Trigger.
    20.     // May or may not apply to YOUR case depends on how you are doing collisions.
    21.     olFrameColliders[index].isTrigger = true;
    22. }
    23.  
    24. // Now initialize to the correct image the snake should start out displaying
    25. curFrame = 0;
    26. oldFrame = -1;
    27. oSpriteRenderer.sprite = aImages[curFrame];
    28.  
    29. // Enable the collider associated with the current frame
    30. EnableCollider(true);

    This goes into the Update() method:
    Code (CSharp):
    1. // if the current frame is different from the frame displayed last update
    2. if (curFrame != oldFrame)
    3. {
    4.     // display the current sprite (frame)
    5.     oSpriteRenderer.sprite = aImages[curFrame];
    6.  
    7.     // enable the associated polygon collider
    8.     EnableCollider(true);
    9.  
    10.      // update the old frame to the current frame
    11.      // so we can detect the next change in the image
    12.     oldFrame = curFrame;
    13. }

    Finally, I have this method to enable / disable the collider(s) as needed
    Code (CSharp):
    1. private void EnableCollider(bool TrueOrFalse)
    2. {
    3.     // always disable the old collider
    4.     olFrameColliders[oldFrame].enabled = false;
    5.  
    6.     // enable or disable the current collider as requested
    7.     olFrameColliders[curFrame].enabled = TrueOrFalse;
    8. }

    The above approach works very well. I tested a slightly more involved version last winter with Unity animations and it worked fine. Encountered no performance issues.

    I just updated the enemy snakes in my platform game tonight to use the above simplified approach (easier since I am no longer using the Unity animations). It works great.

    Maybe this will help you. If not, it may be helpful to someone else. I know I searched for several days last winter before coming to the conclusion I needed to devise my own method. I just figured Unity would have support built-in for this kind of thing since it is such a fundamental requirement of game development.
     
    Last edited: Oct 1, 2014
  7. adrianrodriguez

    adrianrodriguez

    Joined:
    May 29, 2013
    Posts:
    16
    @GarBenjamin Do you think you could show me what happens in the Unity app when this code is running. I'm trying to visualize certain aspects of it. I understand some, but not all and I welcome any approach that works well, and may save time vs the opposite.
     
  8. GarBenjamin

    GarBenjamin

    Joined:
    Dec 26, 2013
    Posts:
    7,441
    Not at the moment because I am "at work". Yes, I do work from home but still I don't do personal work on company time. I probably visit these forums way more than I should but I justify that as much needed brain breaks. ;)

    I can tell you what happens though. Each of the snake enemies in my game start out with no colliders. When they appear in the game they have 6 polygon colliders attached to them, one for each image they can display, with the collider associated with the current image they are displaying being the only one enabled and the other 5 colliders are disabled. As the snake animates the active collider cycles through the 6. It just enables the first, the second and so forth based on which image (or Sprite as Unity calls them) is currently being displayed. The previously enabled collider is disabled so there is always only one collider enabled at any one time.
     
  9. adrianrodriguez

    adrianrodriguez

    Joined:
    May 29, 2013
    Posts:
    16
    Ah ok, understood. Also, I feel you on the brain breaks, mine are similar. I visit forums, or sketch out my game, or mess with Unity.
     
    GarBenjamin likes this.
  10. GarBenjamin

    GarBenjamin

    Joined:
    Dec 26, 2013
    Posts:
    7,441
    How's your project coming along? Have you tried implementing the auto collider generation system?

    One thing I notice is the polygon colliders Unity adds (at least through code) seem to be larger than they should be. It is not a huge issue but I'd definitely prefer the colliders to fit tighter to the actual image. Or maybe they will fix their algo in an upcoming update. I think it would be ideal if we could specify the amount of gap between the image and collider or else specify the number of points to use. With more points automatically following the shape of the image better of course.
     
  11. adrianrodriguez

    adrianrodriguez

    Joined:
    May 29, 2013
    Posts:
    16
    I was actually away for a few days and haven't touched this yet. I don't quite understand how to do it, but when I approach it I will let you know. Been spending more time sketching and laying out things lately overall.
     
  12. Seiya

    Seiya

    Joined:
    Sep 1, 2014
    Posts:
    7
    Hi, I was just looking for something similar since I was trying to use dynamic collidrs for my sprites. I'm curious as to why it has to be so difficult to do something which should be so trivial. Clearly if we're programing a 2D game, we're all most likely going to be using sprites and most likely they're going to have to be animated with different poses. I'd have thought the 2D system should have something that helps us do this :/

    Well anyways, i'm going to try and figure out how to get your code to work since I'm not a a C sharp programmer, and thanks :)
     
  13. CgShady

    CgShady

    Joined:
    Mar 31, 2011
    Posts:
    10
    Hi,

    first, thanks to GarBenjamin, your example saved me time.

    I ended up doing it fully automatic, so it detects the sprite changes and builds the colliders automatically. Enabling/disabling the script also enables/disables the current sprite collider.

    Let me know if you face any performance issue.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class AnimatedSpriteCollider : MonoBehaviour
    6. {
    7.     public bool iStrigger ;
    8.     public PhysicsMaterial2D _material ;
    9.    
    10.     private SpriteRenderer spriteRenderer;
    11.     private List<Sprite> spritesList;
    12.     private Dictionary<int, PolygonCollider2D> spriteColliders;
    13.     private bool _processing ;
    14.  
    15.     private int _frame ;
    16.     public int Frame
    17.     {
    18.         get { return _frame ; }
    19.         set
    20.         {
    21.             if (value != _frame)
    22.             {
    23.                 if (value > -1)
    24.                 {
    25.                     spriteColliders[_frame].enabled = false;
    26.                     _frame = value ;
    27.                     spriteColliders[_frame].enabled = true;
    28.                 }
    29.                 else
    30.                 {
    31.                     _processing = true ;
    32.                     StartCoroutine (AddSpriteCollider (spriteRenderer.sprite)) ;
    33.                 }
    34.             }
    35.         }
    36.     }
    37.  
    38.     private void OnEnable ()
    39.     {
    40.         spriteColliders[Frame].enabled = true;
    41.     }
    42.  
    43.     private void OnDisable ()
    44.     {
    45.         spriteColliders[Frame].enabled = false;
    46.     }
    47.  
    48.     private IEnumerator AddSpriteCollider (Sprite sprite)
    49.     {
    50.         spritesList.Add (sprite) ;
    51.         int index = spritesList.IndexOf (sprite);
    52.         PolygonCollider2D spriteCollider = gameObject.AddComponent<PolygonCollider2D>();
    53.         spriteCollider.isTrigger = iStrigger;
    54.         spriteCollider.sharedMaterial = _material;
    55.         spriteColliders.Add(index, spriteCollider);
    56.         yield return new WaitForEndOfFrame () ;
    57.         Frame = index ;
    58.         _processing = false ;
    59.     }
    60.  
    61.     private void Awake ()
    62.     {
    63.         spriteRenderer = this.GetComponent<SpriteRenderer>();
    64.  
    65.         spritesList = new List<Sprite> () ;
    66.  
    67.         spriteColliders = new Dictionary<int, PolygonCollider2D>();
    68.  
    69.         Frame = spritesList.IndexOf (spriteRenderer.sprite) ;
    70.     }
    71.  
    72.     private void LateUpdate ()
    73.     {
    74.         if (!_processing)
    75.             Frame = spritesList.IndexOf (spriteRenderer.sprite) ;
    76.     }
    77. }
     
    Sungold, PiperPro and GarBenjamin like this.
  14. GarBenjamin

    GarBenjamin

    Joined:
    Dec 26, 2013
    Posts:
    7,441
    Nice! That is similar to how I originally did it last winter when I was using the Unity Animator.
    I performed a check at run time to see if a collider had been generated for the current image and if not, it was created. So, basically what happened was the first time a given Game Object displayed a specific image the collider was generated at that time. But this time around I figured why not just generate them all up front during the start and then during the actual Update I don't need to mess even checking for the collider existing.

    Still, it is always good to present another option. And I agree with Seiya, it is strange that we even need to do this kind of thing ourselves. Unity has so much in it you would expect that something so fundamental to 2D game development would be built-in!
     
  15. garraeth

    garraeth

    Joined:
    Apr 20, 2014
    Posts:
    10
    Just wanted to post to say you guys rock, THANKS! Kudos to both GarBenjamin and CgShady.
     
  16. PabloUnityArgentina

    PabloUnityArgentina

    Joined:
    Oct 13, 2014
    Posts:
    7
    First of all, thank you very much for posting this.

    I think, anyway, that the code GarBenjamin posted can be improved. I think we do not have to animate the sprites and generates the animation manually by settting the sprite variable. I think, the Animator component has to do that. We just only have to know the list of sprites that the animation has (this perhaps can by made by accesing the animator component). We have to let the Animator component animates automatically (That's the way Unity does, and also by doing it this way, we can use the Animator State System, otherwise not). Then we have to know what frame are being displayed in a particular moment of the animation (By asking to the animator component); then we only have to switch to the correct polygon collider as GarBenjamin made.

    That will do that our script only focuses on switch from one polygon collider to another, and not by animating the sprite.

    Thank you very much for posting this. Let me know what you think about my thoughts.

    Edit: I have done my own version of the script by changing some things. This code it is almost the same as the code from GarBenjamin, but it Loads sprites automatically (without manual configuration) using Resources.LoadAll.

    In addition, it manages all the states (animations) from a Animator Controller, not only one animation. It does not animate anything, the Animator component (From Unity) animates all and this script only focuses on enabling / disabling Polygon Colliders in order to match with the current frame of the animation that is being displayed.

    It is permanently syncronized with the animation that is being played...so every frame it knows what poylgon collider has to be on.

    Let me know what you think.

    pd: You have to create a Resources folder and create folders with the same name of the animation you are using. Inside this folder, you have to put the sprites that the animation uses. You have to do this for every animation on the animation controller. Notes that there is only two public variables on the script. You have to configurate them first. And that's it.
     
    Last edited: Oct 6, 2015
  17. PabloUnityArgentina

    PabloUnityArgentina

    Joined:
    Oct 13, 2014
    Posts:
    7
    Code (CSharp):
    1. [code=CSharp]using UnityEngine;
    2. using System.Collections.Generic;
    3. using UnityEditor;
    4.  
    5. public class AutoGeneratePolygonColliders : MonoBehaviour
    6. {
    7.     // Array of images for the snake's animation.
    8.     // This is loaded in the Inspector.
    9.     public bool isTrigger;
    10.     public List<AnimationClip> animationClips;
    11.  
    12.     private List<ListWrapper> aImages;
    13.  
    14.     // Dictionary containing an integer frame (sprite) index
    15.     // and the associated polygon collider.
    16.     private List<Dictionary<int, PolygonCollider2D>> olFrameColliders;
    17.  
    18.     // tracks the current frame
    19.     private int curFrame;
    20.  
    21.     // tracks the previous frame
    22.     private int oldFrame;
    23.  
    24.     // a reference to this game object's Sprite Renderer
    25.     private SpriteRenderer oSpriteRenderer;
    26.  
    27.     private Animator animator;
    28.     private int currentClipIndex;
    29.     private int antClipIndex;
    30.  
    31.     void Awake()
    32.     {
    33.         animator = GetComponent<Animator> ();
    34.         oSpriteRenderer = this.GetComponent<SpriteRenderer>();
    35.         olFrameColliders = new List<Dictionary<int, PolygonCollider2D>> ();
    36.         aImages = new List<ListWrapper>();
    37.  
    38.         for (int clip = 0; clip < animationClips.Count; clip++)
    39.         {
    40.             // This section creates the colliders for this snake
    41.             // First we need to instantiate the Dictionary.
    42.  
    43.             //Debug.Log("Inicio animacion nro" + clip + " name " +  animationClips[clip].name);
    44.             olFrameColliders.Add(new Dictionary<int, PolygonCollider2D>());
    45.             aImages.Add(new ListWrapper());
    46.  
    47.             int spriteIndex = 0;
    48.  
    49.             Sprite[] sprites = Resources.LoadAll<Sprite>(animationClips[clip].name);
    50.  
    51.             while(spriteIndex < sprites.Length)
    52.             {
    53.                 aImages[clip].myList.Add(sprites[spriteIndex]);
    54.  
    55.                 // switch to the current image we are processing
    56.                 oSpriteRenderer.sprite = aImages[clip].myList[spriteIndex];
    57.  
    58.                 // create the polygon collider and add it to the Dictionary
    59.                 olFrameColliders[clip].Add(spriteIndex, gameObject.AddComponent<PolygonCollider2D>());
    60.  
    61.                 // disable the collider
    62.                 olFrameColliders[clip][spriteIndex].enabled = false;
    63.  
    64.                 // set this as a Trigger.
    65.                 // May or may not apply to YOUR case depends on how you are doing collisions.
    66.                 olFrameColliders[clip][spriteIndex].isTrigger = isTrigger;
    67.  
    68.                 //Debug.Log("Agregado sprite " + sprites[spriteIndex].name);
    69.  
    70.                 spriteIndex++;
    71.             }
    72.         }
    73.      
    74.         // Now initialize to the correct image the snake should start out displaying
    75.         curFrame = 0;
    76.         oldFrame = -1;
    77.         //oSpriteRenderer.sprite = aImages[curFrame];
    78.      
    79.         // Enable the collider associated with the current frame
    80.         EnableCollider(true);
    81.         antClipIndex = -1;
    82.  
    83.  
    84.     }
    85.  
    86.     void LateUpdate()
    87.     {
    88.         currentClipIndex = animationClips.IndexOf (animator.GetCurrentAnimatorClipInfo (0) [0].clip);
    89.         CheckChangeClip ();
    90.         curFrame = GetCurFrame ();
    91.         // if the current frame is different from the frame displayed last update
    92.  
    93.         //Debug.Log ("frame " + curFrame);
    94.         if (curFrame != oldFrame)
    95.         {
    96.             // display the current sprite (frame)
    97.             //oSpriteRenderer.sprite = aImages[curFrame];
    98.          
    99.             // enable the associated polygon collider
    100.             EnableCollider(true);
    101.          
    102.             // update the old frame to the current frame
    103.             // so we can detect the next change in the image
    104.             oldFrame = curFrame;
    105.         }
    106.     }
    107.  
    108.     private void CheckChangeClip()
    109.     {
    110.         if (currentClipIndex != antClipIndex)
    111.         {
    112.             if(antClipIndex != -1)
    113.             {
    114.                 //Debug.Log("Disable because new clip " + antClipIndex + " " + oldFrame);
    115.                 olFrameColliders [antClipIndex][oldFrame].enabled = false;
    116.             }
    117.             antClipIndex = currentClipIndex;
    118.  
    119.             //Debug.Log("Nuevo clip " + currentClipIndex);
    120.         }
    121.     }
    122.  
    123.     private void EnableCollider(bool TrueOrFalse)
    124.     {
    125.         if (olFrameColliders [antClipIndex].ContainsKey(oldFrame))
    126.         {
    127.             // always disable the old collider
    128.             //Debug.Log("Disable " + antClipIndex + " " + oldFrame);
    129.             olFrameColliders [antClipIndex][oldFrame].enabled = false;
    130.         }
    131.  
    132.         // enable or disable the current collider as requested
    133.         olFrameColliders[currentClipIndex][curFrame].enabled = TrueOrFalse;
    134.     }
    135.  
    136.     private int GetCurFrame()
    137.     {
    138.         // Get the state info from the animator controlling your sprite animation
    139.         AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
    140.         float normalizedTime = stateInfo.normalizedTime - Mathf.Floor(stateInfo.normalizedTime);
    141.         // Here we get the current frame using the animationPercent
    142.         int curFrame = Mathf.FloorToInt(normalizedTime * aImages[currentClipIndex].myList.Count);
    143.         return curFrame;
    144.     }
    145. }
    [/code]
     
  18. Xavy_clay

    Xavy_clay

    Joined:
    Oct 2, 2015
    Posts:
    20
    Hi there!

    I'm fairly new to the community and to Unity, but I found I face the same issues the OP faced back then.

    I gave a quick look at the post and want to ask: is this still a better way to go than full Animator? I'm still trying with Animator and animation sprites but if going full code is gonna give me better results and save me time, I'll switch right now :)

    Thanks for the post.

    Edit: I think I'll have issues with sprite sizes, as some sprites are smaller than others (idle spirtes are stand still, attacks are widther); will this code help me with that? Are there other ways?
     
  19. RemDust

    RemDust

    Joined:
    Aug 28, 2015
    Posts:
    432
    First of all, thank you for this man.
    I know it's been a while but :
    It actually "works" but I'm having crashing issues...
    I've got a pretty complex enemy, big spritesheet for it, and quiet a lot of animations for him.
    That basically mean that the script is building 1collider per sprite per animation, which is like 100colliders just for the torso ^^

    My question is then : how is it even possible to "animate" colliders for a sophisticated 2D game with Unity ?! :/
     
  20. dasdadsaads

    dasdadsaads

    Joined:
    Oct 31, 2013
    Posts:
    1
    I've simplified solution:
    Code (CSharp):
    1.   public class ColliderAdjuster : MonoBehaviour
    2.     {
    3.         [Tooltip("It will load from ../Resources/<PathToSprites>")]
    4.         public string PathToSprites;
    5.        
    6.         private PolygonCollider2D currentCollider;
    7.         private Dictionary<Sprite, Vector2[]> spriteColliderVectors;
    8.         private SpriteRenderer spriteRenderer;
    9.         private void Awake()
    10.         {
    11.             this.spriteRenderer = this.GetComponent<SpriteRenderer>();
    12.             this.currentCollider = this.GetComponent<PolygonCollider2D>();
    13.             this.spriteColliderVectors = new Dictionary<Sprite, Vector2[]>();
    14.  
    15.             var spriteList = Resources.LoadAll<Sprite>(PathToSprites);
    16.            
    17.             foreach (var item in spriteList)
    18.             {
    19.                 var temp = new GameObject();
    20.                 temp.AddComponent<SpriteRenderer>().sprite = item;
    21.                 spriteColliderVectors.Add(item, temp.AddComponent<PolygonCollider2D>().points);
    22.                 Destroy(temp);
    23.             }
    24.         }
    25.         private void Update()
    26.         {
    27.             currentCollider.points = spriteColliderVectors[spriteRenderer.sprite];
    28.         }
    29.     }
    Add script to object you're animating, copy name of folder you have your sprites in to PathToSprites.
    It will generate collider points once during runtime; I don't think there is a point to check frame/sprite/animation changes, as it complicates process and adds more code.
    In this script update just changes pointer's address, which is cheaper than comparing (pulling two object's data);
    For a large game you can run this script and export collider points to JSON, and then load them, instead.