【问题标题】:How to get size of parent game object?如何获取父游戏对象的大小?
【发布时间】:2012-08-14 09:30:01
【问题描述】:

我有三个子游戏对象(如下图所示,RedPink & Blue)。它们是父游戏对象 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 或零。 请帮助我如何获取父(绿色)游戏对象的大小?

【问题讨论】:

    标签: unity3d


    【解决方案1】:

    你所说的大小是指边界吗?如果是这样,它应该比你做的简单得多。我的代码未经测试,我手边没有 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”之类的名称,您可以相当轻松地查找它们,但创建父对象要简单得多。

    【讨论】:

    • 感谢您的回答。它可以工作,但我必须将 MeshRenderer 附加到每个父级并且没有用,我不想将任何组件附加到父级(如果可能)。 有没有第一行的替代方案:Bounds bounds = parent.renderer.bounds;?
    • 八年后,这个解决方案仍然帮助了我,谢谢!注意:bounds.encapsulate 应该是 bounds.Encapsulate。但是提交修订的更改太小了。文档:docs.unity3d.com/ScriptReference/Bounds.Encapsulate.html.
    【解决方案2】:

    这是一篇较旧的帖子,但我有类似的需求,但由于一些问题而遇到了一些问题

    第一次我注意到我计算出来的父框比它应该的要宽,而且它没有正确居中

    原因是我的对象应用了旋转,而边界永远不会这样做;所以在运行我的计算之前,我首先需要旋转回零;然后一旦计算出来,我就可以恢复原来的旋转。

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

    下面是我想出的结果代码;重型cmets;没有优化,但可以解决问题,如果您愿意,可以考虑孙子,并在开始时处理具有旋转的对象。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-02
      相关资源
      最近更新 更多