Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by $$anonymous$$ · Aug 25, 2014 at 01:14 AM · gameobjectmeshboundsbox

Bounds Finding Box

I am trying to get the bounds of a weirdly shaped thing with crazy meshness. I get it that it is not as easy as gameObject.bounds. I figured the easiest way (based on the inconclusive results in my research) is to put a box such as a collider or cube around each gameObject, and just grab the bounds of that. My question is, what object should I use? Is there an object out there that is already intended for this? Or do I need to make a cube and make it translucent and such?

Final Question:

What do I wrap around a GameObject in order to get the bounds of that GameObject via the wrapper?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
3
Best Answer

Answer by robertbu · Aug 25, 2014 at 01:23 AM

I'm assuming you want an AABB (Axis Aligned Bounting Box) around all of the objects. If you need the best possible bounds:

  • Take the mesh.bounds from each object.

  • Calculate the eight corners

  • For each corner, convert it from local to world space using Transform.TransformPoint().

  • Find the minimum and maximum x,y, and z. Coordinate.

  • Repeat with each game object using the same x, y, and z minimums and maximums.

At the end you will have the minimum and maximum values of a box around all of your objects. If you need it, it would be easy to construct a bounds from that data.

Here are two functions. GetBounds() creates an axes aligned bounding box around an array of game objects. GetBoundsPointsNoAlloc() takes a game object and a Vector3[8], and fill the array with the mesh bounding box in world space. These points are not axes aligned. They are both static functions, so if you have a Utility class where you keep static functions, you can toss them in there:

 using UnityEngine;
 using System.Collections;
 
 public static class Utils {
 
 // Gets an axis aligned bound box around an array of game objects
     public static Bounds GetBounds(GameObject[] objs) {
         if (objs == null || objs.Length == 0) {
             return new Bounds(Vector3.zero, Vector3.zero);
         }
 
         float minX =  Mathf.Infinity;
         float maxX = -Mathf.Infinity;
         float minY =  Mathf.Infinity;
         float maxY = -Mathf.Infinity;
         float minZ =  Mathf.Infinity;
         float maxZ = -Mathf.Infinity;
 
         Vector3[] points = new Vector3[8];
 
         foreach (GameObject go in objs) {
             GetBoundsPointsNoAlloc(go, points);
             foreach (Vector3 v in points) {
                 if (v.x < minX) minX = v.x;
                 if (v.x > maxX) maxX = v.x;
                 if (v.y < minY) minY = v.y;
                 if (v.y > maxY) maxY = v.y;
                 if (v.z < minZ) minZ = v.z;
                 if (v.z > maxZ) maxZ = v.z;
             }
         }
     
         float sizeX = maxX - minX;
         float sizeY = maxY - minY;
         float sizeZ = maxZ - minZ;
 
         Vector3 center = new Vector3(minX + sizeX / 2.0f, minY + sizeY / 2.0f, minZ + sizeZ / 2.0f);
 
         return new Bounds(center, new Vector3(sizeX, sizeY, sizeZ));
     }
 
 // Pass in a game object and a Vector3[8], and the corners of the mesh.bounds in 
 //   in world space are returned in the passed array;
     public static void GetBoundsPointsNoAlloc(GameObject go, Vector3[] points) {
         if (points == null || points.Length < 8) {
             Debug.Log ("Bad Array");
             return;
         }
         MeshFilter mf = go.GetComponent<MeshFilter>();
         if (mf == null) {
             Debug.Log ("No MeshFilter on object");
             for (int i = 0; i < points.Length; i++)
                 points[i] = go.transform.position;
             return;
         }
 
         Transform tr = go.transform;
 
         Vector3 v3Center  = mf.mesh.bounds.center;
         Vector3 v3ext = mf.mesh.bounds.extents;
 
         points[0]  = tr.TransformPoint(new Vector3(v3Center.x - v3ext.x, v3Center.y + v3ext.y, v3Center.z - v3ext.z));  // Front top left corner
         points[1]  = tr.TransformPoint(new Vector3(v3Center.x + v3ext.x, v3Center.y + v3ext.y, v3Center.z - v3ext.z));  // Front top right corner
         points[2]  = tr.TransformPoint(new Vector3(v3Center.x - v3ext.x, v3Center.y - v3ext.y, v3Center.z - v3ext.z));  // Front bottom left corner
         points[3]  = tr.TransformPoint(new Vector3(v3Center.x + v3ext.x, v3Center.y - v3ext.y, v3Center.z - v3ext.z));  // Front bottom right corner
         points[4]  = tr.TransformPoint(new Vector3(v3Center.x - v3ext.x, v3Center.y + v3ext.y, v3Center.z + v3ext.z));  // Back top left corner
         points[5]  = tr.TransformPoint(new Vector3(v3Center.x + v3ext.x, v3Center.y + v3ext.y, v3Center.z + v3ext.z));  // Back top right corner
         points[6]  = tr.TransformPoint(new Vector3(v3Center.x - v3ext.x, v3Center.y - v3ext.y, v3Center.z + v3ext.z));  // Back bottom left corner
         points[7]  = tr.TransformPoint(new Vector3(v3Center.x + v3ext.x, v3Center.y - v3ext.y, v3Center.z + v3ext.z));  // Back bottom right corner
     }
 }


And here is a class that I used to test the code. If you want to see the bounding box in Game view, you will need Gizmos turned on in the upper right corner of the Game window:

 using UnityEngine;
 using System.Collections;
 
 public class Testing : MonoBehaviour {
 
     Bounds bounds;
 
     void Update() {
             bounds = Utils.GetBounds (GameObject.FindGameObjectsWithTag("Enemy"));
     }
 
     void OnDrawGizmos() {
             Gizmos.DrawWireCube (bounds.center, bounds.size);
     }
 }


Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image $$anonymous$$ · Aug 25, 2014 at 01:49 AM 0
Share

@robertbu By any chance can you write some generic code? This question has been asked on this site (in different words) half a dozen times without a clear answer.

This is the best answer I have seen yet, but it still requires a lot of knowledge that people who ask this question do not have.

This is what I came up with for trying to deter$$anonymous$$e height via your much appreciated help, :-) if you wouldn't $$anonymous$$d continuing to help me:

 float GetHeight(GameObject thing)
 {
     Bounds bounds = thing.GetComponent<$$anonymous$$eshRenderer>().bounds;
     Vector3 topLeft = new Vector3(bounds.$$anonymous$$.x, bounds.max.y, bounds.$$anonymous$$.z);
     Vector3 bottomLeft = new Vector3(bounds.$$anonymous$$.x, bounds.$$anonymous$$.y, bounds.$$anonymous$$.z);
     topLeft = thing.transform.TransformPoint(topLeft);
     bottomLeft = thing.transform.TransformPoint(bottomLeft);
     return topLeft.y - bottomLeft.y;
 }

(obviously, my code does not work.)

avatar image robertbu · Aug 25, 2014 at 04:25 AM 0
Share

I edited my answer to include some code.

avatar image $$anonymous$$ · Aug 25, 2014 at 04:17 PM 0
Share

thank you for that wonderful code! i am still getting too small of a bounding box, so my error must be elsewhere. I'll just stick a cube around my object for now. I greatly appreciate your help!!

avatar image robertbu · Aug 25, 2014 at 04:25 PM 0
Share

I tested the code with a variety of object and positions before I posted it. It always produced a precise bounds to the objects. You have to take a look at the result along the world axes in Scene view to verify since any perspective makes it difficult to tell if all the object are inside the bounds. If you need a bit of space in addition to the exact bounds, you can use Bounds.Expand() to expand the bounds after it is returned.

avatar image $$anonymous$$ · Aug 25, 2014 at 04:45 PM 0
Share

@robertbu i think the problem lays with the polygon tool i am using from the asset store. your code works absolutely amazingly with everything except for those polygons! (the $$anonymous$$ and max y are both the same)

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

2 People are following this question.

avatar image avatar image

Related Questions

Is there an easy way to get on-screen render size (bounds)? 5 Answers

not working- GameObject.GetComponent(MeshFilter).mesh; 1 Answer

C# Preserving GameObjects' Previous Meshes 1 Answer

how to hide the mesh of the gameobject ? 1 Answer

Turning off renderer in other game object (C#) 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges