当前位置:   article > 正文

Unity3d bounds包围盒 和collider碰撞器区别_collider.bounds

collider.bounds

Bounds 外包围盒

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

Render.bounds 世界坐标

Collider.bounds 世界坐标

Mesh.bounds  本地坐标

  1. var m= GetComponent<MeshFilter>().bounds;
  2. var c = GetComponent<Collider>().bounds;
  3. var r = GetComponent<Renderer>().bounds;

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

  1. //把本地坐标换算成世界坐标
  2. var centerPoint = transform.TransformPoint(bounds.center);
  3. 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 常用方法

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

多物体Bounds, Encapsulate方法

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

  1. Bounds bounds;
  2. Renderer[] renderers = model.GetComponentsInChildren<Renderer>();
  3. for (int i = 0; i < renderers.Length; i++)
  4. {
  5.     bounds.Encapsulate(renderers[i].bounds);
  6. }


 

计算包围盒的八个顶点

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

 

绘制bounds方框

  1. /// <summary>
  2. /// 绘制Bounds方框
  3. /// </summary>
  4. /// <param name="bounds"></param>
  5. /// <param name="color"></param>
  6. /// <param name="offsetSize"></param>
  7. /// <param name="duration"></param>
  8. public static void DrawBoundBoxLine(Bounds bounds, Color color = default(Color), float offsetSize = 1f, float duration = 0.1f)
  9. {
  10. //先计算出包围盒8个点
  11. Vector3[] points = new Vector3[8];
  12. var width_x = bounds.size.x * offsetSize;
  13. var hight_y = bounds.size.y * offsetSize;
  14. var length_z = bounds.size.z * offsetSize;
  15. var LeftBottomPoint = bounds.min;
  16. var rightUpPoint = bounds.max;
  17. var centerPoint = bounds.center;
  18. var topPoint = new Vector3(centerPoint.x, centerPoint.y + hight_y / 2, centerPoint.z);
  19. var bottomPoint = new Vector3(centerPoint.x, centerPoint.y - hight_y * 0.5f, centerPoint.z);
  20. points[0] = LeftBottomPoint + Vector3.right * width_x;
  21. points[1] = LeftBottomPoint + Vector3.up * hight_y;
  22. points[2] = LeftBottomPoint + Vector3.forward * length_z;
  23. points[3] = rightUpPoint - Vector3.right * width_x;
  24. points[4] = rightUpPoint - Vector3.up * hight_y;
  25. points[5] = rightUpPoint - Vector3.forward * length_z;
  26. points[6] = LeftBottomPoint;
  27. points[7] = rightUpPoint;
  28. Debug.DrawLine(LeftBottomPoint, points[0], color, duration);
  29. Debug.DrawLine(LeftBottomPoint, points[1], color, duration);
  30. Debug.DrawLine(LeftBottomPoint, points[2], color, duration);
  31. Debug.DrawLine(rightUpPoint, points[3], color, duration);
  32. Debug.DrawLine(rightUpPoint, points[4], color, duration);
  33. Debug.DrawLine(rightUpPoint, points[5], color, duration);
  34. Debug.DrawLine(points[1], points[3], color, duration);
  35. Debug.DrawLine(points[2], points[4], color, duration);
  36. Debug.DrawLine(points[0], points[5], color, duration);
  37. Debug.DrawLine(points[2], points[3], color, duration);
  38. Debug.DrawLine(points[0], points[4], color, duration);
  39. Debug.DrawLine(points[1], points[5], color, duration);
  40. }

绘制碰撞器方框 -方法1

  1. /// <summary>
  2. /// 绘制boxCollider的绿色方框
  3. /// </summary>
  4. /// <param name="color"></param>
  5. void DrawGizmosOnRunTime(Color color)
  6. {
  7. var boxCollider = GetComponent<BoxCollider>();
  8. Gizmos.color = color;
  9. Matrix4x4 rotationMatrix = Matrix4x4.TRS(boxCollider.transform.position, boxCollider.transform.rotation, boxCollider.transform.lossyScale);
  10. Gizmos.matrix = rotationMatrix;
  11. Gizmos.DrawWireCube(boxCollider.center, boxCollider.size);
  12. }
  13. void OnDrawGizmos()
  14. {
  15. DrawGizmosOnRunTime(Color.red);
  16. }

绘制碰撞器方框 -方法2

  1. /// <summary>
  2. /// 绘制boxCollider的绿色方框
  3. /// </summary>
  4. /// <param name="boxCollider"></param>
  5. /// <param name="color"></param>
  6. /// <param name="offsetSize"></param>
  7. public static void DrawOnGameViewRuntime(BoxCollider boxCollider, Color color = default(Color), float offsetSize = 1f)
  8. {
  9. float width = 0.1f;
  10. Vector3 rightDir = boxCollider.transform.right.normalized;
  11. Vector3 forwardDir = boxCollider.transform.forward.normalized;
  12. Vector3 upDir = boxCollider.transform.up.normalized;
  13. Vector3 center = boxCollider.transform.position + boxCollider.center;
  14. Vector3 size = boxCollider.size * offsetSize;
  15. size.x *= boxCollider.transform.lossyScale.x;
  16. size.y *= boxCollider.transform.lossyScale.y;
  17. size.z *= boxCollider.transform.lossyScale.z;
  18. 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);
  19. 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);
  20. 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);
  21. 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);
  22. 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);
  23. 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);
  24. 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);
  25. 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);
  26. 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);
  27. 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);
  28. 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);
  29. 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);
  30. }

求两个包围盒之间的距离

  1. // Distance between two ClosestPointOnBounds
  2. // this is needed in cases where entites are really big. in those cases,
  3. // we can't just move to entity.transform.position, because it will be
  4. // unreachable. instead we have to go the closest point on the boundary.
  5. //
  6. // Vector3.Distance(a.transform.position, b.transform.position):
  7. // _____ _____
  8. // | | | |
  9. // | x==|======|==x |
  10. // |_____| |_____|
  11. //
  12. //
  13. // Utils.ClosestDistance(a.collider, b.collider):
  14. // _____ _____
  15. // | | | |
  16. // | |x====x| |
  17. // |_____| |_____|
  18. //
  19. public static float ClosestDistance(Collider a, Collider b)
  20. {
  21. return Vector3.Distance(a.ClosestPointOnBounds(b.transform.position),
  22. b.ClosestPointOnBounds(a.transform.position));
  23. }

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

 计算所有包围盒的中心点

计算出多个Bounds的中心点

  1. [MenuItem ("MyMenu/Do Test")]
  2. static void Test ()
  3. {
  4. Transform parent = Selection.activeGameObject.transform;
  5. Vector3 postion = parent.position;
  6. Quaternion rotation = parent.rotation;
  7. Vector3 scale = parent.localScale;
  8. parent.position = Vector3.zero;
  9. parent.rotation = Quaternion.Euler(Vector3.zero);
  10. parent.localScale = Vector3.one;
  11. Vector3 center = Vector3.zero;
  12. Renderer[] renders = parent.GetComponentsInChildren<Renderer>();
  13. foreach (Renderer child in renders){
  14. center += child.bounds.center;
  15. }
  16. center /= parent.GetComponentsInChildren<Transform>().Length;
  17. Bounds bounds = new Bounds(center,Vector3.zero);
  18. foreach (Renderer child in renders){
  19. bounds.Encapsulate(child.bounds);
  20. }
  21. parent.position = postion;
  22. parent.rotation = rotation;
  23. parent.localScale = scale;
  24. foreach(Transform t in parent){
  25. t.position = t.position - bounds.center;
  26. }
  27. parent.transform.position = bounds.center + parent.position;
  28. }

参考 

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/390808
推荐阅读
相关标签
  

闽ICP备14008679号