Bounds 叫作外包围盒、边界框、外扩矩形.是struct 结构体。
而我们获得Bounds的主要途径有三种:Render,Collider,Mesh。
Render.bounds 世界坐标
Collider.bounds 世界坐标
Mesh.bounds 本地坐标
- var m= GetComponent
().bounds; - var c = GetComponent
().bounds; - var r = GetComponent
().bounds;
- //把本地坐标换算成世界坐标
- var centerPoint = transform.TransformPoint(bounds.center);
- Bounds newBounds = new Bounds(centerPoint, bounds.size);
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
- // 点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 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方框
- ///
- ///
- ///
- ///
- ///
- 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);
- }
- ///
- /// 绘制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);
- }
- ///
- /// 绘制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));
- }
计算出多个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