How can I change my polygon collider to correctly represent each frame in a sprite?

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?

As 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.

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 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.

This is definitely achievable.

Although this is not a real answer, but it should be documented; 2D ColliderGen has this as a feature.