如下图所示,拖入不同的mesh在一个节点下面,自动生成一个BoxCollider包围盒。这个功能可以方便关卡策划,不然手动设置BoxCollider太蛋疼了。。
先选择一个父节点,然后执行下面脚本。。 或者也可以根据需求在关卡编辑器上做成自动的。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
[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; } center /= parent.GetComponentsInChildren().Length; Bounds bounds = new Bounds(center,Vector3.zero); foreach (Renderer child in renders){ bounds.Encapsulate(child.bounds); } BoxCollider boxCollider = parent.gameObject.AddComponent<BoxCollider>(); boxCollider.center = bounds.center - parent.position; boxCollider.size = bounds.size; parent.position = postion; parent.rotation = rotation; parent.localScale = scale; } |
避免子节点中有残留的Collider,生成前先把所有子节点的Collider删除。
参考文章 http://stackoverflow.com/questions/11949463/how-to-get-size-of-parent-game-object
- 本文固定链接: https://www.xuanyusong.com/archives/3461
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!
The type arguments for method ‘Component.GetComponentsInChildren()’ cannot be inferred from the usage. Try specifying the type arguments explicitly.
大佬,这怎么弄呢
雨松大大超级棒棒,看了雨松大大的第二版游戏开发,很细节,都是一些底层。超级棒。
欢迎提出宝贵意见~
我是新手,请问这个脚本完成需要什么条件?(是否需要继承editor或者继承其他)
早上也用编辑器实现了这个需求,用的是先添加子render的bounds到boundsList再逐个合并bounds bounds.Encapsulate这个函数可以直接接bounds 这个学习了后面的转化用的 transform.InverseTransformPoint和InverseTransformVector来做的,学习了。分享下个人的代码:[MenuItem(“Test/AddBoxCollisionInChoose”)] static void AddBoxCollisionInChoose() { targetObj = Selection.activeGameObject; if (targetObj) { if(boundsList!=null) boundsList.Clear(); boundsList = new List(); Renderer[] rends = targetObj.GetComponentsInChildren(); for (int i = 0; i < rends.Length; i ) { BoxCollider box=rends .gameObject.AddComponent(); boundsList.Add(box.bounds); } Bounds parentBox = new Bounds(targetObj.transform.position, Vector3.zero); foreach (Bounds bound in boundsList) { parentBox = TestPoint(parentBox, bound.center); parentBox = TestPoint(parentBox, bound.min); parentBox = TestPoint(parentBox, bound.max); } BoxCollider mybox=targetObj.AddComponent(); mybox.center = targetObj.transform.InverseTransformPoint(parentBox.center); mybox.size = targetObj.transform.InverseTransformVector(parentBox.size); for (int i = 0; i < rends.Length; i ) { BoxCollider box = rends .gameObject.GetComponent(); box.enabled = false; UnityEngine.Object.DestroyImmediate(box); } } } private static Bounds TestPoint(Bounds parent, Vector3 point) { if (parent.Contains(point) == false) { parent.Encapsulate(point); } return parent; }
早上也用编辑器实现了这个需求,用的是先添加子render的bounds到boundsList再逐个合并bounds bounds.Encapsulate这个函数可以直接接bounds 这个学习了后面的转化用的 transform.InverseTransformPoint和InverseTransformVector来做的,学习了。分享下个人的代码:[MenuItem(“Test/AddBoxCollisionInChoose”)] static void AddBoxCollisionInChoose() { targetObj = Selection.activeGameObject; if (targetObj) { if(boundsList!=null) boundsList.Clear(); boundsList = new List(); Renderer[] rends = targetObj.GetComponentsInChildren(); for (int i = 0; i < rends.Length; i++) { BoxCollider box=rends .gameObject.AddComponent(); boundsList.Add(box.bounds); } Bounds parentBox = new Bounds(targetObj.transform.position, Vector3.zero); foreach (Bounds bound in boundsList) { parentBox = TestPoint(parentBox, bound.center); parentBox = TestPoint(parentBox, bound.min); parentBox = TestPoint(parentBox, bound.max); } BoxCollider mybox=targetObj.AddComponent(); mybox.center = targetObj.transform.InverseTransformPoint(parentBox.center); mybox.size = targetObj.transform.InverseTransformVector(parentBox.size); for (int i = 0; i < rends.Length; i++) { BoxCollider box = rends .gameObject.GetComponent(); box.enabled = false; UnityEngine.Object.DestroyImmediate(box); } } } private static Bounds TestPoint(Bounds parent, Vector3 point) { if (parent.Contains(point) == false) { parent.Encapsulate(point); } return parent; }
刚学习,发现21行应该
center /= parent.childCount;
下一篇center /= parentTransform.GetComponentsInChildren().Length;
ok
我想在场景中设置一些点,然后用线把他们连起来,编辑场景的时候有没有可以画线的功能呢?就像在场景中看摄像机或者其他模型似得,有不同颜色的线框可以标识
debug.line 就可以画线。
看了MOMO关于编辑器扩展的一系列文章,感觉受益匪浅,对unity底层的一些运行时有了新的认识。非常感谢!
新版本的Unity的扩展方法和老版本的Unity有区别吗
没区别
MOMO 关卡编辑器能提供下思路吗??
就是让策划挂脚本。。。 主要还是看是什么样的关卡了。
最近也在研究编辑器扩展和插件,能否共享一些学习资料,谢谢~
主要是你想知道具体的什么内容呢?
关卡过程设计,技能编辑这块,哈哈,参考参考
感觉最近会用上,mark一下
我们策划已经开始用啦。。 如果有问题我会及时补充的。。
沙发
谢谢。