Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Get vertices of box collider

Discussion in 'Scripting' started by bbvrdev, May 14, 2011.

Thread Status:
Not open for further replies.
  1. bbvrdev

    bbvrdev

    Joined:
    Aug 11, 2009
    Posts:
    221
    Gentlemen,
    Is there an easy way to get the world positions of the vertices of a box collider? I am trying to plot a waypoint system based on the corners of boxes.

    Thanks!
     
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    If the boxes aren't rotated, then it would be straightforward to use collider.bounds.center / collider.bounds.extents.

    --Eric
     
  3. bbvrdev

    bbvrdev

    Joined:
    Aug 11, 2009
    Posts:
    221
    Unfortunately they're rotated :) I tried that already hoping it would work, but the points were all out of whack.
     
  4. jgodfrey

    jgodfrey

    Joined:
    Nov 14, 2009
    Posts:
    564
    Use Eric's suggestion, but rotate the points to match a known orientation of the collider or mimic the collider with a rotated cube and get its vertices?
     
  5. bbvrdev

    bbvrdev

    Joined:
    Aug 11, 2009
    Posts:
    221
    Thanks! How would I mimic the collider with a rotated cube? The collider is already attached to a cuboid gameobject.
     
  6. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    If the collider matches the mesh, then use Mesh.bounds, which is in local space.
     
  7. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    This is the only way I can think of to do it using just a collider, no mesh:

    Code (csharp):
    1. function GetColliderVertexPositions (object : GameObject) : Vector3[] {
    2.     var vertices = new Vector3[8];
    3.     var thisMatrix = object.transform.localToWorldMatrix;
    4.     var storedRotation = object.transform.rotation;
    5.     object.transform.rotation = Quaternion.identity;
    6.    
    7.     var extents = object.collider.bounds.extents;
    8.     vertices[0] = thisMatrix.MultiplyPoint3x4(extents);
    9.     vertices[1] = thisMatrix.MultiplyPoint3x4(Vector3(-extents.x, extents.y, extents.z));
    10.     vertices[2] = thisMatrix.MultiplyPoint3x4(Vector3(extents.x, extents.y, -extents.z));
    11.     vertices[3] = thisMatrix.MultiplyPoint3x4(Vector3(-extents.x, extents.y, -extents.z));
    12.     vertices[4] = thisMatrix.MultiplyPoint3x4(Vector3(extents.x, -extents.y, extents.z));
    13.     vertices[5] = thisMatrix.MultiplyPoint3x4(Vector3(-extents.x, -extents.y, extents.z));
    14.     vertices[6] = thisMatrix.MultiplyPoint3x4(Vector3(extents.x, -extents.y, -extents.z));
    15.     vertices[7] = thisMatrix.MultiplyPoint3x4(-extents);
    16.    
    17.     object.transform.rotation = storedRotation;
    18.     return vertices;
    19. }
    Pass in a game object with a collider, and it returns a Vector3 array of the 8 corners in world space.

    --Eric
     
    raymondy1, Danyellow, mikaelK and 4 others like this.
  8. bbvrdev

    bbvrdev

    Joined:
    Aug 11, 2009
    Posts:
    221
    That's great Eric, thank you! I'll put that to good use :)
     
  9. Cawas

    Cawas

    Joined:
    Jan 14, 2010
    Posts:
    121
    Would you happen to know what's the difference on using Transform.localToWorldMatrix and Transform.TransformPoint ? The docs seem to say it makes no difference, but on my brief tests it did.
     
  10. Tom163

    Tom163

    Joined:
    Nov 30, 2007
    Posts:
    1,293
    For some reason, the above from eric doesn't work for me, but this here does:

    Code (CSharp):
    1.     void OnDrawGizmosSelected() {
    2.         BoxCollider b = GetComponent<BoxCollider>();
    3.  
    4.         Gizmos.color = Color.green;
    5.         Gizmos.DrawSphere(transform.TransformPoint(b.center + new Vector3(b.size.x, -b.size.y, b.size.z)*0.5f), 5f);
    6.         Gizmos.DrawSphere(transform.TransformPoint(b.center + new Vector3(-b.size.x, -b.size.y, b.size.z)*0.5f), 5f);
    7.         Gizmos.DrawSphere(transform.TransformPoint(b.center + new Vector3(-b.size.x, -b.size.y, -b.size.z)*0.5f), 5f);
    8.         Gizmos.DrawSphere(transform.TransformPoint(b.center + new Vector3(b.size.x, -b.size.y, -b.size.z)*0.5f), 5f);
    9.     }
    10.  
    11.  
     
    TH3_TWIN, Shiiv, mikaelK and 2 others like this.
  11. nbg_yalta

    nbg_yalta

    Joined:
    Oct 3, 2012
    Posts:
    378
    Handy, thanks!
     
    TimLoo6 likes this.
  12. MaximilianPs

    MaximilianPs

    Joined:
    Nov 7, 2011
    Posts:
    323
    And for the Noobs like me :rolleyes:, the code that you'll need is this one
    (where go is your gameObject)

    Code (CSharp):
    1.  
    2. Vector3[] verts = new Vector3[4];        // Array that will contain the BOX Collider Vertices
    3.         BoxCollider b = go.GetComponent<BoxCollider>();
    4.  
    5.         verts[0] = b.center + new Vector3(b.size.x, -b.size.y, b.size.z) * 0.5f;
    6.         verts[1] = b.center + new Vector3(-b.size.x, -b.size.y, b.size.z) * 0.5f;
    7.         verts[2] = b.center + new Vector3(-b.size.x, -b.size.y, -b.size.z) * 0.5f;
    8.         verts[3] = b.center + new Vector3(b.size.x, -b.size.y, -b.size.z) * 0.5f;
    9.  
    Thank you very much it works great ! ;)
     
    tariingo263 likes this.
  13. 40detectives

    40detectives

    Joined:
    Apr 9, 2016
    Posts:
    74
    Thank you!! I've been messing around trying to get the correct points a whole day but in the end, this was much easier and fast.
     
  14. TimLoo6

    TimLoo6

    Joined:
    Dec 29, 2019
    Posts:
    6
    It's the obvious way to do it, worked perfectly for me and I was about to post the same code
     
  15. borakopumo

    borakopumo

    Joined:
    Feb 27, 2020
    Posts:
    1
    The code from above has an issue that when game obj is rotated bounds extends get scaled and they don't represent the actual box anymore. There's also no need to cache and set game obj rotation.

    Code (CSharp):
    1. public static void GetBoxPoints2D(this BoxCollider2D box, Vector2[] points)
    2.         {
    3.             var size = box.size * 0.5f;
    4.  
    5.             var mtx = Matrix4x4.TRS(box.bounds.center, box.transform.localRotation, box.transform.localScale);
    6.  
    7.             points[0] = mtx.MultiplyPoint3x4(new Vector3(-size.x, size.y));
    8.             points[1] = mtx.MultiplyPoint3x4(new Vector3(-size.x, -size.y));
    9.             points[2] = mtx.MultiplyPoint3x4(new Vector3(size.x, -size.y));
    10.             points[3] = mtx.MultiplyPoint3x4(new Vector3(size.x, size.y));
    11.         }
    Example is in 2d, for 3d just add more points and z-axis.
    It works whether your game object is rotated or scaled or whatever.
     
  16. MaciekOaky

    MaciekOaky

    Joined:
    Nov 10, 2016
    Posts:
    6
    To make it even cleaner you can use Bounds.

    Code (CSharp):
    1.  Bounds localBounds = new Bounds(boxCollider.center, boxCollider.size);
    Code (CSharp):
    1. private void OnDrawGizmosSelected()
    2.     {
    3.         BoxCollider boxCollider = GetComponent<BoxCollider>();
    4.  
    5.         Bounds localBounds = new Bounds(boxCollider.center, boxCollider.size);
    6.  
    7.         const float radius = 0.1f;
    8.  
    9.         Gizmos.color = Color.green;
    10.  
    11.         Gizmos.DrawSphere(transform.TransformPoint(new Vector3(localBounds.min.x, localBounds.min.y, localBounds.min.z)), radius);
    12.         Gizmos.DrawSphere(transform.TransformPoint(new Vector3(localBounds.min.x, localBounds.min.y, localBounds.max.z)), radius);
    13.         Gizmos.DrawSphere(transform.TransformPoint(new Vector3(localBounds.max.x, localBounds.min.y, localBounds.max.z)), radius);
    14.         Gizmos.DrawSphere(transform.TransformPoint(new Vector3(localBounds.max.x, localBounds.min.y, localBounds.min.z)), radius);
    15.     }
    The best way is to make it as an extension method for a collider:
    Code (CSharp):
    1. public static Bounds GetLocalBounds(this BoxCollider boxCollider)
    2.         {
    3.             return new Bounds(boxCollider.center, boxCollider.size);
    4.         }
    and get it like that:
    Code (CSharp):
    1. boxCollider.GetLocalBounds().min.x
     
    MaxIzrinCubeUX likes this.
  17. Digika

    Digika

    Joined:
    Jan 7, 2018
    Posts:
    227
    None of these take into account parent's rotation. All suggested approaches break when Parent is rotated and double-broken when both parent and target object with a collider is rotated.
    Good effort tho
     
    trombonaut, ChainTechDev and Braza like this.
Thread Status:
Not open for further replies.