如何获得父游戏对象的大小?

时间:2012-08-14 09:30:02

标签: unity3d

我有三个儿童游戏对象(如下图所示,红色粉红色& 蓝色)。他们是父游戏对象Green的孩子。

我不知道,如何计算父(绿色) GameObject 的大小?

我在运行时使用以下代码创建所有这些游戏对象:

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;    
    }

此函数在添加所有子项后返回父(绿色)gameObject。我的父母(绿色)没有任何东西,甚至没有任何组件(BoxCollider,MeshFilter,MeshRenderer等)。

我附上了BoxCollider,MeshRenderer& MeshFilter(仅供测试)&我试过父母:

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

但没有任何作用。在案例中返回1或0。 请帮助我了解如何获得Parent(Green)GameObject的大小?

enter image description here

2 个答案:

答案 0 :(得分:25)

按大小你的意思是界限?如果是这样,它应该比你做的简单得多。我的代码未经测试,我没有Unity方便,但这应该工作。它假设“父”是层次结构中的游戏对象,并且在层次结构中它下面有“子”。

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

更新

或者,如果您不希望父级具有渲染器:

// 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);   
}

您提到不想使用父/子层次结构。如果你没有走那条路,你需要将“children”添加到某种数组中,或者你必须使用GameObject.Find()方法按名称查找每个子节点。如果你命名为“child_1”,“child_2”之类的东西,你可以很容易地查找它们,但是简单地创建一个父对象就简单了很多。

答案 1 :(得分:1)

这是一篇较老的帖子,但我有类似的需求并因为一些问题而遇到了一些问题

第一次我注意到我计算的父盒子比它应该更宽并且它没有居中对象

原因是我的对象有一个旋转应用于它们,并且界限永远不会;所以在运行我的计算之前,我首先需要回转到零;然后一旦计算,我就可以恢复原来的旋转。

第二个在我的情况下,并非我的所有子对象都有渲染器,此外我的孩子可能有自己的孩子所以我不想在变换孩子上计算中心我希望子渲染组件。

以下是我提出的结果代码;沉重的评论;没有优化但是诀窍,如果你愿意的话会占孙子,并且在开始时处理旋转对象。

        //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;