Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

What are bounds?

Discussion in 'Scripting' started by NidoAnxari, Jul 1, 2017.

  1. NidoAnxari

    NidoAnxari

    Joined:
    Jan 2, 2017
    Posts:
    86
    I am almost new to scripting and facing trouble understanding the bounds and how they work. As far as I can understand is that they are like boundaries around a gameobject. But following are some questions that I am unable to understand:
    1. Do they completely cover/overlap the gameobject or just of some regular shape like circle, rectangle or square.
    2. Can we get a point on a bound and convert it to local space position?
    3. Can we use colliders as a bound and get a point on that collider and convert it to local space?
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,385
    So GameObject's don't have bounds.

    Also, bounds can mean many things... like bounds of an array.

    From the context though, it sounds like you're talking about the Bounds struct:
    https://docs.unity3d.com/ScriptReference/Bounds.html

    And you can get them from things like:
    Collider.bounds:
    https://docs.unity3d.com/ScriptReference/Collider-bounds.html
    Mesh.bounds:
    https://docs.unity3d.com/ScriptReference/Mesh-bounds.html
    Renderer.bounds:
    https://docs.unity3d.com/ScriptReference/Renderer-bounds.html

    The bounds represent different things in each case.

    But basically from the documentation:
    So a 'Bounds' is an axis aligned bounding box... AABB.

    This means a box, or rectoid, in 3-space... that can't be rotated. It's locked to the x/y/z axes.

    In the case of a Collider.bounds. It is a AABB that fits around the collider. Think if you had a sphere collider... the bounds would be a cube in which the sphere perfectly fits.

    Mesh.bounds is the same thing... but around a mesh.

    And Renderer.bounds is the same thing... but is the space made up of where rendering occurs for that object.

    It's always larger than the thing it's bounding.

    The fact it's axis aligned though... means that any rotation of oblong shaped things distort the bounding box a lot.

    Bounding boxes are good to get very approximate relative locations of things. Since bounding box intersection is a very simple and fast calculation (relative to complex collision or similar)... you can rule out things being anywhere near each other if their bounding boxes don't intersect. Sure, they might not be intersecting even if the bounds are intersecting... but if the bounds don't, then they certainly aren't. It'd be like saying "can Sally touch Sam?"... "Well Sam and Sally aren't in the same room, so surely Sally can't touch Sam".

    Or if say you have a view frustum, if the bounding box and view frustum don't overlap... then the thing isn't on screen... again, not complex intersection calculations to do... just basic bounding calculations.
     
  3. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    One gotcha about Bounds to watch out for is code like this:

    Code (csharp):
    1.  
    2.             Bounds _worldBox = new Bounds();
    3.  
    4.             for (var i = 0; i < renderers.Length; ++i)
    5.             {
    6.                 _worldBox.Encapsulate(renderers[i].bounds);
    7.             }
    8.  
    If you do a "new Bounds()", the position (0,0,0) is part of the bounds, which you probably don't want.
     
    FullMe7alJacke7 and Vorrin like this.
  4. NidoAnxari

    NidoAnxari

    Joined:
    Jan 2, 2017
    Posts:
    86
    Thanks to both of you guys!
     
  5. Vorrin

    Vorrin

    Joined:
    Jan 14, 2013
    Posts:
    10
    Such nice answers, it warms the heart :)
     
  6. ratneshpatel

    ratneshpatel

    Joined:
    Oct 10, 2017
    Posts:
    21
    The problem with bounds is that it doesn't work well for rotated objects because then the bounds would be not the same as collider volume.
     
  7. jhocking-bundlar

    jhocking-bundlar

    Joined:
    Nov 12, 2019
    Posts:
    24
    er, could you elaborate on why there is a problem, and what you want instead? I'm currently debugging code that looks like what you posted, so perhaps I am hitting the issue you refer to, but I can't tell what's actually wrong.
     
  8. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,385
    If you call encapsulate, it inflates/grows the bounds from its current position/size to encompass both itself AND the bounds passed in.

    The problem is that the starting bounds are of dimensions 0 at position 0. Basically it's a bounds encapsulating a single point (that point being 0,0,0).

    When it inflates to say encapsulate bounds at 100,0,0 with say size 1,1,1... you'll end up with a box encapsulating both... basically a box that is size 100.5,1,1 and positioned probably around 50.25,0,0.

    See the problem?

    So in BlackPete's code... the intent of the code at first glance appears to give you a bounding box that encompasses every bounds in the renderer list... but actually it encompasses every bound in the renderer list AND a 0 sized bound at 0,0,0. If those bounds happen to overlap that 0 bound, it's fine... but if those bounds aren't near the origin. Yeah, it's going to be a big problem.

    So really... for BlackPete's code to properly get what the implied intent is would be to do something like:
    Code (csharp):
    1.  
    2. var conjoinedbounds = renderers[0].bounds;
    3. for(int i = 1; i < renderers.Length; i++)
    4. {
    5.     conjoinedbounds.Encapsulate(renderers[i].bounds);
    6. }
    7.  
     
    jhocking-bundlar likes this.
  9. jhocking-bundlar

    jhocking-bundlar

    Joined:
    Nov 12, 2019
    Posts:
    24
    Thanks for the explanation! That makes sense, and yeah that was the problem I was encountering (my model's origin was far off the actual mesh). In my case, I couldn't assume every object had a renderer, so I needed to do descendant.TryGetComponent<Renderer>(out var childRenderer) and then instead of simply using the first object's renderer, while looping do the check in this first snippet:

    https://answers.unity.com/questions/724635/how-does-boundsencapsulate-work.html
     
    Last edited: Feb 10, 2021