9

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

我不知道,如何计算 Parent(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;    
    }

添加所有孩子后,此函数返回父(绿色)游戏对象。我的父级(绿色)没有任何附加内容,甚至没有任何组件(BoxCollider、MeshFilter、MeshRenderer 等)。

我已附加 BoxCollider、MeshRenderer 和 MeshFilter(仅用于测试)并且我在父级上尝试过:

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

但没有任何效果。在某些情况下返回 1 或零。请帮助我如何获取父(绿色)游戏对象的大小?

在此处输入图像描述

4

2 回答 2

30

大小是指边界吗?如果是这样,它应该比你做的简单得多。我的代码未经测试,我手边没有 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);   
}

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

于 2012-08-14T21:21:41.567 回答
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;
于 2014-04-09T23:47:58.717 回答