Unity3d bounds包围盒 和collider碰撞器区别
创始人
2024-03-07 18:32:40
0

Bounds 外包围盒

Bounds 叫作外包围盒、边界框、外扩矩形.是struct 结构体。而我们获得Bounds的主要途径有三种:Render,Collider,Mesh。

Render.bounds 世界坐标

Collider.bounds 世界坐标

Mesh.bounds  本地坐标

        var m= GetComponent().bounds;var c = GetComponent().bounds;var r = GetComponent().bounds;

把 Mesh.bounds 本地坐标换算成世界坐标bounds 

  //把本地坐标换算成世界坐标var centerPoint = transform.TransformPoint(bounds.center);Bounds newBounds = new Bounds(centerPoint, bounds.size);

碰撞器绿方框

Bounds和碰撞器的绿方框(绿色线)的区别

碰撞器的方框始终跟着模型旋转移动,缩放跟着模型的,只要模型不缩放它也不缩放

Bounds 跟随模型移动,而不会跟模型着旋转,而是随着模型旋转而缩放变大变小,始终包裹模型.

下面红色方框就是 Bounds 方框

Bounds属性

只读属性

我们不能直接修改 Bounds 结构体里头的 center 和 size 属性都不能直接设置,而且 BoxCollider 的 bounds 属性也不能.

.bounds.center;  //中心点坐标
.bounds.size;        //盒子的总尺寸,xyz长度
.bounds.min;            //最小点的位置:左下角
.bounds.max;                //最大点的位置:右上角
.bounds.center.x;            //中心点的X
.bounds.center.y;                //中心点的Y

Bounds 常用方法

// 点point是否在这个包围盒内部
public bool Contains(Vector3 point);// bounds会自动扩充大小(改变center和extens),来包含这个point
public void Encapsulate(Vector3 point);// bounds会自动扩充大小(改变center和extens),把原本的bounds和传入的bounds都包含进来
public void Encapsulate(Bounds bounds);// 这条射线是否与这个包围盒相交
public bool IntersectRay(Ray ray);//包围盒最近的点
public Vector3 ClosestPoint(Vector3 point);//设置边界框的最小最大值
public void SetMinMax(Vector3 min, Vector3 max);

多物体Bounds, Encapsulate方法

计算多物体Bounds,则要遍历所有子物体,然后调用Encapsulate方法来计算。

Bounds bounds;
Renderer[] renderers = model.GetComponentsInChildren();
for (int i = 0; i < renderers.Length; i++)
{bounds.Encapsulate(renderers[i].bounds);
}


 

计算包围盒的八个顶点

center = bounds.center;
ext = bounds.extents;float deltaX = Mathf.Abs(ext.x);
float deltaY = Mathf.Abs(ext.y);
float deltaZ = Mathf.Abs(ext.z);#region 获取AABB包围盒顶点
points = new Vector3[8];
points[0] = center + new Vector3(-deltaX, deltaY, -deltaZ);        // 上前左(相对于中心点)
points[1] = center + new Vector3(deltaX, deltaY, -deltaZ);         // 上前右
points[2] = center + new Vector3(deltaX, deltaY, deltaZ);          // 上后右
points[3] = center + new Vector3(-deltaX, deltaY, deltaZ);         // 上后左points[4] = center + new Vector3(-deltaX, -deltaY, -deltaZ);       // 下前左
points[5] = center + new Vector3(deltaX, -deltaY, -deltaZ);        // 下前右
points[6] = center + new Vector3(deltaX, -deltaY, deltaZ);         // 下后右
points[7] = center + new Vector3(-deltaX, -deltaY, deltaZ);        // 下后左
#endregion

 

绘制bounds方框

    /// /// 绘制Bounds方框/// /// /// /// /// public static void DrawBoundBoxLine(Bounds bounds, Color color = default(Color), float offsetSize = 1f, float duration = 0.1f){//先计算出包围盒8个点Vector3[] points = new Vector3[8];var width_x = bounds.size.x * offsetSize;var hight_y = bounds.size.y * offsetSize;var length_z = bounds.size.z * offsetSize;var LeftBottomPoint = bounds.min;var rightUpPoint = bounds.max;var centerPoint = bounds.center;var topPoint = new Vector3(centerPoint.x, centerPoint.y + hight_y / 2, centerPoint.z);var bottomPoint = new Vector3(centerPoint.x, centerPoint.y - hight_y * 0.5f, centerPoint.z);points[0] = LeftBottomPoint + Vector3.right * width_x;points[1] = LeftBottomPoint + Vector3.up * hight_y;points[2] = LeftBottomPoint + Vector3.forward * length_z;points[3] = rightUpPoint - Vector3.right * width_x;points[4] = rightUpPoint - Vector3.up * hight_y;points[5] = rightUpPoint - Vector3.forward * length_z;points[6] = LeftBottomPoint;points[7] = rightUpPoint;Debug.DrawLine(LeftBottomPoint, points[0], color, duration);Debug.DrawLine(LeftBottomPoint, points[1], color, duration);Debug.DrawLine(LeftBottomPoint, points[2], color, duration);Debug.DrawLine(rightUpPoint, points[3], color, duration);Debug.DrawLine(rightUpPoint, points[4], color, duration);Debug.DrawLine(rightUpPoint, points[5], color, duration);Debug.DrawLine(points[1], points[3], color, duration);Debug.DrawLine(points[2], points[4], color, duration);Debug.DrawLine(points[0], points[5], color, duration);Debug.DrawLine(points[2], points[3], color, duration);Debug.DrawLine(points[0], points[4], color, duration);Debug.DrawLine(points[1], points[5], color, duration);}

绘制碰撞器方框 -方法1

    /// /// 绘制boxCollider的绿色方框/// /// void DrawGizmosOnRunTime(Color color){var boxCollider = GetComponent();Gizmos.color = color;Matrix4x4 rotationMatrix = Matrix4x4.TRS(boxCollider.transform.position, boxCollider.transform.rotation, boxCollider.transform.lossyScale);Gizmos.matrix = rotationMatrix;Gizmos.DrawWireCube(boxCollider.center, boxCollider.size);}void OnDrawGizmos(){DrawGizmosOnRunTime(Color.red);}

绘制碰撞器方框 -方法2

    /// /// 绘制boxCollider的绿色方框/// /// /// /// public static void DrawOnGameViewRuntime(BoxCollider boxCollider, Color color = default(Color), float offsetSize = 1f){float width = 0.1f;Vector3 rightDir = boxCollider.transform.right.normalized;Vector3 forwardDir = boxCollider.transform.forward.normalized;Vector3 upDir = boxCollider.transform.up.normalized;Vector3 center = boxCollider.transform.position + boxCollider.center;Vector3 size = boxCollider.size * offsetSize;size.x *= boxCollider.transform.lossyScale.x;size.y *= boxCollider.transform.lossyScale.y;size.z *= boxCollider.transform.lossyScale.z;Debug.DrawLine(center + upDir * size.y / 2f + rightDir * size.x / 2f + forwardDir * size.z / 2f, center + upDir * size.y / 2f - rightDir * size.x / 2f + forwardDir * size.z / 2f, color);Debug.DrawLine(center - upDir * size.y / 2f + rightDir * size.x / 2f + forwardDir * size.z / 2f, center - upDir * size.y / 2f - rightDir * size.x / 2f + forwardDir * size.z / 2f, color);Debug.DrawLine(center + upDir * size.y / 2f + rightDir * size.x / 2f + forwardDir * size.z / 2f, center - upDir * size.y / 2f + rightDir * size.x / 2f + forwardDir * size.z / 2f, color);Debug.DrawLine(center + upDir * size.y / 2f - rightDir * size.x / 2f + forwardDir * size.z / 2f, center - upDir * size.y / 2f - rightDir * size.x / 2f + forwardDir * size.z / 2f, color);Debug.DrawLine(center + upDir * size.y / 2f + rightDir * size.x / 2f - forwardDir * size.z / 2f, center + upDir * size.y / 2f - rightDir * size.x / 2f - forwardDir * size.z / 2f, color);Debug.DrawLine(center - upDir * size.y / 2f + rightDir * size.x / 2f - forwardDir * size.z / 2f, center - upDir * size.y / 2f - rightDir * size.x / 2f - forwardDir * size.z / 2f, color);Debug.DrawLine(center + upDir * size.y / 2f + rightDir * size.x / 2f - forwardDir * size.z / 2f, center - upDir * size.y / 2f + rightDir * size.x / 2f - forwardDir * size.z / 2f, color);Debug.DrawLine(center + upDir * size.y / 2f - rightDir * size.x / 2f - forwardDir * size.z / 2f, center - upDir * size.y / 2f - rightDir * size.x / 2f - forwardDir * size.z / 2f, color);Debug.DrawLine(center + upDir * size.y / 2f + rightDir * size.x / 2f + forwardDir * size.z / 2f, center + upDir * size.y / 2f + rightDir * size.x / 2f - forwardDir * size.z / 2f, color);Debug.DrawLine(center - upDir * size.y / 2f + rightDir * size.x / 2f + forwardDir * size.z / 2f, center - upDir * size.y / 2f + rightDir * size.x / 2f - forwardDir * size.z / 2f, color);Debug.DrawLine(center + upDir * size.y / 2f - rightDir * size.x / 2f + forwardDir * size.z / 2f, center + upDir * size.y / 2f - rightDir * size.x / 2f - forwardDir * size.z / 2f, color);Debug.DrawLine(center - upDir * size.y / 2f - rightDir * size.x / 2f + forwardDir * size.z / 2f, center - upDir * size.y / 2f - rightDir * size.x / 2f - forwardDir * size.z / 2f, color);}

求两个包围盒之间的距离

    // Distance between two ClosestPointOnBounds// this is needed in cases where entites are really big. in those cases,// we can't just move to entity.transform.position, because it will be// unreachable. instead we have to go the closest point on the boundary.//// Vector3.Distance(a.transform.position, b.transform.position)://    _____        _____//   |     |      |     |//   |  x==|======|==x  |//   |_____|      |_____|////// Utils.ClosestDistance(a.collider, b.collider)://    _____        _____//   |     |      |     |//   |     |x====x|     |//   |_____|      |_____|//public static float ClosestDistance(Collider a, Collider b){return Vector3.Distance(a.ClosestPointOnBounds(b.transform.position),b.ClosestPointOnBounds(a.transform.position));}

 求点A到包围盒最近的点,ClosestPoint

 计算所有包围盒的中心点

计算出多个Bounds的中心点

[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;Vector3 center = Vector3.zero;Renderer[] renders = parent.GetComponentsInChildren();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);   }parent.position = postion;parent.rotation = rotation;parent.localScale = scale;foreach(Transform t in parent){t.position = t.position -  bounds.center;}parent.transform.position = bounds.center + parent.position;}

参考 

  https://blog.csdn.net/sinat_25415095/article/details/104588989

https://www.5axxw.com/questions/content/imitu9

相关内容

热门资讯

嫦娥 李商隐 嫦娥 李商隐嫦娥 李商隐,此其诗诗题为“嫦娥”,实际上抒写的是处境孤寂的主人公对于环境的感受和心灵独...
咏秋古诗词 中秋将至,秋风猎猎,秋高气爽。作为我国的传统节日,古代诗词中有很多千古传颂的咏秋之作,以诗抒情怀,以...
谷雨的古诗句 谷雨的古诗句  谷雨的雨,现身在古代文人墨客笔下,是相当愁人的。小编今天为大家带来关于谷雨的.古诗句...
表达奉献精神的诗句 表达奉献精神的诗句  在日常学习、工作和生活中,大家总少不了接触一些耳熟能详的诗句吧,诗句能使人们自...
经典爱情现代诗   经典爱情现代诗  1、《炉中煤》  啊,我年青的女郎!  我不辜负你的殷勤,  你也不要辜负了我...
描写兰花的诗句分享 描写兰花的诗句分享  丛兰生幽谷,莓莓遍林薄。不纫亦何伤,已胜当门托。辇至逾关山,滋培珍几阁。  冬...
朱自清的代表作品有哪些 朱自清的代表作品有哪些  朱自清(1898.11.22—1948.8.12)原名自华,号秋实,后改名...
春思诗,春思诗谢朓,春思诗的... 春思诗,春思诗谢朓,春思诗的意思,春思诗赏析 -诗词大全  春思诗,春思诗谢朓,春思诗的意思,春思诗...
客醉倚河桥,清光愁玉箫 “客醉倚河桥,清光愁玉箫。”出处 出自 宋代 高观国 的《菩萨蛮·何须急管吹云暝》“客醉倚河桥,清光...
古代的诗词歌赋 古代的诗词歌赋五篇  导语:诗词歌赋是专门集我国历代名家精品如唐诗宋词元曲为一体的诗词歌赋作品的软件...
唯美古诗句子 唯美古诗句子  山无陵,江水为竭,冬雷震震,夏雨雪,天地合,乃敢与君绝!下文就是有关描写唯美古诗句子...
花的古诗 关于花的古诗大全  古诗是古代中国诗歌的泛称,指古代中国人创作的诗歌作品。广义的古诗包括诗、词、散曲...
《武陵春·风住尘香花已尽》李... 《武陵春·风住尘香花已尽》李清照宋词翻译及赏析  赏析,是一个汉语词汇,意思是欣赏并分析(诗文等),...
中秋节的诗歌 中秋节的诗歌  1、《月之故乡》  彭邦桢  水里一个月亮  天上一个月亮  天上的月亮在水里  水...
中国经典古诗词 有关中国经典古诗词  在学习、工作或生活中,许多人对一些广为流传的古诗都不陌生吧,古诗是中文独有的一...
描写夏天的古诗 关于描写夏天的古诗  夏天是我们喜爱的季节之一,那么,关于描写夏天的古诗有哪些呢?下面是unjs小编...
苏轼的诗句都有哪些 苏轼的诗句都有哪些  苏轼的诗句都有哪些呢,大家感兴趣了解一下吗?以下是小编为大家整理的关于苏轼的诗...
张爱玲经典语录 张爱玲经典语录100句  在日常的学习、工作、生活中,许多人都接触或是使用过一些比较经典的语录吧,语...
乍咽凉柯,还移暗叶,重把离愁... “乍咽凉柯,还移暗叶,重把离愁深诉。”出处 出自 宋代 王沂孙 的《齐天乐·蝉》“乍咽凉柯,还移暗叶...
“一径穿缘应就郭,千花掩映似... “一径穿缘应就郭,千花掩映似无溪。”这两句是说,一条幽僻的路径,缘山通向寺院的墙外;溪水两旁百花盛开...