Search Unity

Physics2D Bounds and Extents

Discussion in '2D' started by Lovelock, Nov 16, 2013.

  1. Lovelock

    Lovelock

    Joined:
    Nov 6, 2013
    Posts:
    5
    For what it's worth I had a small hiccup and wanted to share my solution with anyone that could use it.

    Previously, with 3D colliders and objects, we had a lovely Bounds object that contains the Extents of our object in x, y, and z. Great for plenty of things. Custom collisions, controllers, raycast origins, special effects, etc. It was as easy as:
    Code (csharp):
    1.  
    2. Vector3 playerExtents = collider.bounds.extents;
    3.  
    Unfortunately, 2D colliders (and renderers) don't seem to have a nice Bounds object to work with. We can, however, reference a BoxCollider2D, or any other 2D collider for that matter.

    After referencing this collider, we can just get the info we want from that. For example:
    Code (csharp):
    1.  
    2. Vector3 extents = GetComponent<BoxCollider2D>().size * 0.5f;
    3.  
    Which can be used to get player extent offsets like so:
    Code (csharp):
    1.  
    2. Vector3 PlayerBottomLeft = new Vector3(-extents.x, -extents.y, 0f);
    3. Vector3 PlayerBottomRight = new Vector3(extents.x, -extents.y, 0f);
    4.  
    And used like so:
    Code (csharp):
    1.  
    2. float rayDist = 2.0f; // Distance to cast rays
    3.  
    4. // Raycast down from bottom left
    5. Vector3 rayOrigin = transform.position + PlayerBottomLeft;
    6. Vector3 rayDirection = Vector3.down;
    7. RaycastHit2D hitBottomLeft = Physics2D.Raycast(rayOrigin, rayDirection, rayDist, groundMask); // groundMask is a simple LayerMask
    8. Debug.DrawRay(rayOrigin, rayDirection * rayDist * hitBottomLeft.fraction, Color.yellow);
    9.  
    Hopefully this will help someone out!

    Also, please let me know if I've missed something. :)
     
  2. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,455
    Unfortunately, retrieving the collider bounds for 2D didn't make it into the 4.3 release however it has already been added and will be available in a future release.

    Hope this helps.
     
  3. dbanfield

    dbanfield

    Joined:
    Apr 20, 2013
    Posts:
    8
    thanks for sharing Lovelock - this saved me some headscratching :)
     
  4. Disaster

    Disaster

    Joined:
    Oct 31, 2009
    Posts:
    43
    Any word on this? Will it be a major release or can we expect it to appear any time soon? Having to use transform to check for collisions is kinda sucky.
     
  5. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,455
    It's not scheduled for a major release so you won't have to wait for that. All improvements are going into releases after 4.3 though.
     
  6. QuapPac

    QuapPac

    Joined:
    Mar 7, 2014
    Posts:
    6
    Apparently there will be a lot more Physics2D additions with Unity5!
     
  7. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,455
    It will be in the 4.5 release as will a majority of the changes that have been spoken about in the forums.
     
  8. SmooveB

    SmooveB

    Joined:
    Jul 26, 2011
    Posts:
    3
    I was trying to figure out where the feet and top of my sprites are so I can have them bop each other Mario style and could not figure out how to get an accurate collision height with 2d. Thanks!
     
  9. SmooveB

    SmooveB

    Joined:
    Jul 26, 2011
    Posts:
    3
    Wait, PolygonCollider2D does not have a size variable. I guess I will just have to loop through PolygonCollider2D.points and find the highest one?
     
  10. Sisso

    Sisso

    Joined:
    Sep 29, 2009
    Posts:
    196
    I add this code to compute object bounds if someone come here searching a solution.

    Code (csharp):
    1. // compute bounds in local space
    2.     public static Bounds BoundsOf(Collider2D collider) {
    3.         var bounds = new Bounds();
    4.  
    5.         var bc = collider as BoxCollider2D;
    6.         if (bc) {
    7.             var ext = bc.size * 0.5f;
    8.             bounds.Encapsulate(new Vector3(-ext.x, -ext.y, 0f));
    9.             bounds.Encapsulate(new Vector3(ext.x, ext.y, 0f));
    10.             return bounds;
    11.         }
    12.  
    13.         var cc = collider as CircleCollider2D;
    14.         if (cc) {
    15.             var r = cc.radius;
    16.             bounds.Encapsulate(new Vector3(-r, -r, 0f));
    17.             bounds.Encapsulate(new Vector3(r, r, 0f));
    18.             return bounds;
    19.         }
    20.  
    21.  
    22. // others :P
    23.         Debug.LogWarning("Unknown type "+bounds);
    24.  
    25.         return bounds;
    26.     }
    27.  
    28. // return bounds in world space
    29.     public static Bounds BoundsColliders(GameObject obj) {
    30.         var bounds = new Bounds(obj.transform.position, Vector3.zero);
    31.  
    32.         var colliders = obj.GetComponentsInChildren<Collider2D>();
    33.         foreach(var c in colliders) {
    34.             var blocal = Utils.BoundsOf(c);
    35.             var t = c.transform;
    36.             var max = t.TransformPoint(blocal.max);
    37.             bounds.Encapsulate(max);
    38.             var min = t.TransformPoint(blocal.min);
    39.             bounds.Encapsulate(min);
    40.         }
    41.  
    42.         return bounds;
    43.     }
    44.  
    This will help to test

    Code (csharp):
    1.  
    2.     void OnDrawGizmos() {
    3.         if (enabled) {
    4.             Gizmos.color = color;
    5.             var bounds = Utils.BoundsColliders(gameObject);
    6.             Gizmos.DrawWireCube(bounds.center, bounds.size);
    7.         }
    8.     }
    9.