Hi everyone, I’ve begun using the 2d tools in unity 4.3 and I’ve run into a bit of a snag. When I attach a polygon collider to my sprite, sure enough, the polygonal shape represents the sprite, but it doesn’t change as the sprite animates. Is this achievable or am I using the component for something it’s not intended for?
5 Answers
5As of Unity 4.3, I believe the only way to do this at this time is to manually create a new Polygon collider for each frame in the animation. Attach all the polygon colliders to your sprite, and enable/disable them as needed throughout the animation with the animation controls.
This obviously won’t work well for “smooth” animations, but animations based on sprite sheets it should do just fine. If this is needed for, say, a swinging sword, typically attaching a BoxCollider to an empty GameObject and animating the transform of the empty is the way to go.
I know this is delayed but it might be helpful… I just ran into this same issue with my first Unity3D game project which is actually in 2D using the new 2D support offered by Unity 4.3.
Anyway, what I came up with is to dynamically generate the Polygon2D colliders and attach them to my objects during run-time.
I just didn’t want to spend the time trying to manually create the colliders for each sprite. That seems like a lot of effort & time to me. In reality, I think the Unity2D system should be creating the colliders and attaching them to the sprite images themselves not the game object. That way when we animate the game objects the colliders will have been prepared beforehand and automatically use the appropriate collider for the current sprite in the animation sequence. Since Unity3D does not actually work that way I decided to write the code to do it for my project.
Basically, all I do is track the list of Polygon2D colliders attached to my game objects.
Whenever my game objects sprite (strange terminology… I am “old school” and sprites to me are the game objects… what Unity3D calls sprites I simply call images or animation frames) anyway, when the image changes I…
- Disable the current active collider.
- Check my list for an existing collider already attached to handle this image.
- If a collider already exists for the image then I simply activate this existing collider.
- If no collider is found for the image then I create a new collider, activate it and add it to my tracking list.
This works fine for my needs. Some of my enemy sprites are quite large (1/4) of the screen and I don’t need many onscreen at one time. Prefer to have less quantity of enemies but make them more intelligent / interesting.
My game won’t ever have more than 16 enemies onscreen at any one time. However, I did test it with 200 enemies and the fps never dropped. This is on my laptop I bought back in 2008 so I think handling the colliders this way is reasonably efficient.
Also, Guidez said “Attach all the polygon colliders to your sprite, and enable/disable them as needed throughout the animation with the animation controls.” I am assuming they mean by setting flags or triggers. As far as I know there is now way to directly map colliders to the states and automatically enable / disable the colliders as part of the animation or states. But maybe I missed that part.
just attach the below code to ur game object which have the animation
public bool iStrigger ;
//public PhysicsMaterial2D _material ;
private SpriteRenderer spriteRenderer;
private List<Sprite> spritesList;
private Dictionary<int, PolygonCollider2D> spriteColliders;
private bool _processing ;
private int _frame ;
public int Frame {
get { return _frame; }
set {
if (value != _frame) {
if (value > -1) {
spriteColliders [_frame].enabled = false;
_frame = value;
spriteColliders [_frame].enabled = true;
} else {
_processing = true;
StartCoroutine (AddSpriteCollider (spriteRenderer.sprite));
}
}
}
}
private IEnumerator AddSpriteCollider (Sprite sprite)
{
spritesList.Add (sprite);
int index = spritesList.IndexOf (sprite);
PolygonCollider2D spriteCollider = gameObject.AddComponent<PolygonCollider2D> ();
spriteCollider.isTrigger = iStrigger;
// spriteCollider.sharedMaterial = _material;
spriteColliders.Add (index, spriteCollider);
yield return new WaitForEndOfFrame ();
Frame = index;
_processing = false;
}
private void OnEnable ()
{
spriteColliders [Frame].enabled = true;
}
private void OnDisable ()
{
spriteColliders [Frame].enabled = false;
}
private void Awake ()
{
spriteRenderer = this.GetComponent<SpriteRenderer> ();
spritesList = new List<Sprite> ();
spriteColliders = new Dictionary<int, PolygonCollider2D> ();
Frame = spritesList.IndexOf (spriteRenderer.sprite);
}
private void LateUpdate ()
{
if (!_processing)
Frame = spritesList.IndexOf (spriteRenderer.sprite);
}
I'm confused, where does this actually load the polygon colider from? Don't you have to create them by hand?
– darthdeusThis is definitely achievable.
Although this is not a real answer, but it should be documented; 2D ColliderGen has this as a feature.
Idk. that's best a question for the developer of the asset. I just wanted this to be known, since I think the asset store is so helpful.
– CarterG81Simply attach a new Collider2D after the sprite is changed, Unity will automatically recalcute the collider size so it fits the current sprite. I suggest you attaching a PolygonCollider2D component if you are looking for precision.
Of course that generanting a new Collider often might cause performance issues.

I'm super late to this, but I was thinking about the same question as the OP, and wanted to know if you had an example of this somewhere?
– adrianrodriguezHey adrianrodriguez. Just noticed your comment. It just so happens that last night I posted the code for how I implement this on the Unity forum. I actually strramlined it since my answer here. Now the colliders are generated all at one time during the initialization phase of the game instead of creating a collider each time a new frame is displayed for the first time in game. You can check it out here: http://forum.unity3d.com/threads/is-it-better-to-use-sprite-swapping-or-animations.271278/#post-1793895
– GarBenjamin