如下图所示,拖入不同的mesh在一个节点下面,自动生成一个BoxCollider包围盒。这个功能可以方便关卡策划,不然手动设置BoxCollider太蛋疼了。。
先选择一个父节点,然后执行下面脚本。。 或者也可以根据需求在关卡编辑器上做成自动的。。
// 为父节点创建包围所有子物体的碰撞盒
[MenuItem ("MyMenu/Do Test")]
static void Test ()
{
Transform parent = Selection.activeGameObject.transform;
Vector3 postion = parent.position;
Quaternion rotation = parent.rotation;
Vector3 scale = parent.localScale;
parent.position = Vector3.zero;
parent.rotation = Quaternion.Euler(Vector3.zero);
parent.localScale = Vector3.one;
Collider[] colliders = parent.GetComponentsInChildren<Collider>();
foreach (Collider child in colliders){
DestroyImmediate(child);
}
// 计算所有物体的中心点
Vector3 center = Vector3.zero;
Renderer[] renders = parent.GetComponentsInChildren<Renderer>();
foreach (Renderer child in renders){
center += child.bounds.center; // renderer.bounds.center即渲染组件的包围盒的中心点
}
center /= parent.GetComponentsInChildren().Length; // 注意:所有子节点,包括子节点的子节点。childCount只包含直接的子节点。
// 创建包围盒,并包围所有renderer
Bounds bounds = new Bounds(center,Vector3.zero); // 在中心点创建
foreach (Renderer child in renders){
bounds.Encapsulate(child.bounds); // 包围盒扩展,直到包围了renderer.bounds包围盒
}
// 创建父节点的碰撞盒
BoxCollider boxCollider = parent.gameObject.AddComponent<BoxCollider>();
boxCollider.center = bounds.center; // 注意,包围盒扩展后,中心点位置会改变(受渲染物体的包围盒影响)。不再是原来创建时的中心点。
boxCollider.size = bounds.size;
parent.position = postion;
parent.rotation = rotation;
parent.localScale = scale;
}
避免子节点中有残留的Collider,生成前先把所有子节点的Collider删除。
参考文章 unity3d - How to get size of parent game object? - Stack Overflow
- 本文固定链接: Unity3D研究院之自动计算所有子对象包围盒(六) | 雨松MOMO程序研究院
- 转载请注明: 雨松MOMO 2015年05月05日 于 雨松MOMO程序研究院 发表