Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get size of parent game object?

Tags:

unity3d

I have three child game objects(as you can see in below picture with Red, Pink & Blue). They are child of parent game object Green.

I don't know, how to calculate size of Parent(Green) GameObject?

I am creating all these game objects at runtime using this code:

GameObject CreatePattern(int difficultyLevel)    
    {    
        GameObject gameObjectTemp = new GameObject();    
        SinglePattern singlePattern;    
        gameObjectTemp = (GameObject) Instantiate(gameObjectTemp);   


        singlePattern = freeRunDataHandler.GetSinglePatternRandom(1);    
        GameObject gameObjectSingleObject = null;    
        foreach (SingleObject singleObject in singlePattern.singleObjectList)    
        {
                gameObjectSingleObject = GetGameObjectByCategory(singleObject.catergory, singleObject.type);

            if (gameObjectSingleObject != null)    
            {    
                gameObjectSingleObject = (GameObject) Instantiate(gameObjectSingleObject, new Vector3(singleObject.positionX, singleObject.positionY, singleObject.positionZ), Quaternion.identity);    
                gameObjectSingleObject.transform.localScale = new Vector3(singleObject.length, 1, singleObject.width);    
                gameObjectSingleObject.transform.parent = gameObjectTemp.transform;    
            }    
        }        

        return gameObjectTemp;    
    }

This function returns parent(Green) gameObject after adding all childs. My Parent(Green) have nothing attached to it not even any component(BoxCollider, MeshFilter, MeshRenderer, etc..).

I had attached BoxCollider, MeshRenderer & MeshFilter(Just for testing) & i tried on parent:

parent.collider.bounds.size.x  ----- > box collider
parent.renderer.bounds.size.x  ----- > mesh renderer

But nothing works. There return 1 or zero in cases. Please help me in how to get size of Parent(Green) GameObject?

enter image description here

like image 211
MicroEyes Avatar asked Aug 14 '12 09:08

MicroEyes


People also ask

How do I get the size of a game object in unity?

If your object has a renderer, you can use renderer. bounds. size , which will return a vector with the height and width (and depth, if it is in 3D).

What is object parenting in unity?

What is Object Parenting? In Unity, objects follow a Hierarchy system. Using this system, GameObjects can become “parents" of other GameObjects. When a GameObject has a parent, it will perform all its transform changes with respect to another GameObject instead of the game world.


2 Answers

By size do you mean the bounds? If so, it should be a lot simpler than you've made it. My code is untested, I don't have Unity handy but this should work. It assumes 'parent' is a game object in your hierarchy and that it has 'children' under it in the hierarchy.

Bounds bounds = parent.renderer.bounds;
foreach (Transform child in parent.transform)
{
    bounds.encapsulate(child.gameObject.renderer.bounds);
}

Update:

Alternatively, if you don't want a parent with a renderer:

// First find a center for your bounds.
Vector3 center = Vector3.zero;

foreach (Transform child in parent.transform)
{
    center += child.gameObject.renderer.bounds.center;   
}
center /= parent.transform.childCount; //center is average center of children

//Now you have a center, calculate the bounds by creating a zero sized 'Bounds', 
Bounds bounds = new Bounds(center,Vector3.zero); 

foreach (Transform child in parent.transform)
{
    bounds.encapsulate(child.gameObject.renderer.bounds);   
}

You mentioned not wanting to use a parent/child hierarchy. If you don't go that route you need to either add the "children" to some sort of array or you'll have to use the GameObject.Find() method to find each child by name. If you name something like "child_1", "child_2" you could look them up fairly easily but it's a hack of a lot simpler to simply create a parent object.

like image 88
Jerdak Avatar answered Oct 09 '22 06:10

Jerdak


This is an older post but I had a similar need and ran into some issues due to a few got-yas

1st I noted that my calculated parent box was wider than it should have been and that it wasn't centered quite right

The cause was that my objects had a rotation applied to them and bounds never do; so before running my calculations I first needed to rotate back around to zero; then once calculated I could restore the original rotation.

2nd in my case not all of my child objects had renderers in addition my children could have children of there own so I dont want to calc center on transform children I wanted the child render components.

Below is the resulting code I came up with; heavy comments; not optimized but does the trick, accounts for grandchildren if you will and handles objects with a rotation on start.

        //Store our current rotation
        Vector3 LocalAngle = transform.localEulerAngles;
        //Zero the rotation before we calculate as bounds are never rotated
        transform.localEulerAngles = Vector3.zero;
        //Establish a default center location
        Vector3 center = Vector3.zero;
        //Establish a default empty bound
        occupiedSpace = new Bounds (Vector3.zero, Vector3.zero);
        //Count the children with renderers
        int count = 0;
        //We only count childrent with renderers which should be fine as the bounds center is global space
        foreach (Renderer render in transform.GetComponentsInChildren<Renderer>()) {
            center += render.bounds.center;  
            count++;
        }
        //Return the average center assuming we have any renderers
        if(count > 0)
            center /= count;
        //Update the parent bound accordingly
        occupiedSpace.center = center;
        //Again for each and only after updating the center expand via encapsulate
        foreach (Renderer render in transform.GetComponentsInChildren<Renderer>()) {
            occupiedSpace.Encapsulate(render.bounds);
        }
        //In by case I want to update the parents box collider so first I need to bring things into local space
        occupiedSpace.center -= transform.position;
        boxCollider.center = occupiedSpace.center;
        boxCollider.size = occupiedSpace.size;
        //Restore our original rotation
        transform.localEulerAngles = LocalAngle;
like image 24
James McGhee Avatar answered Oct 09 '22 06:10

James McGhee