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

news/2024/5/18 16:24:11/文章来源:https://blog.csdn.net/u013628121/article/details/128117992

Bounds 外包围盒

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

Render.bounds 世界坐标

Collider.bounds 世界坐标

Mesh.bounds  本地坐标

        var m= GetComponent<MeshFilter>().bounds;var c = GetComponent<Collider>().bounds;var r = GetComponent<Renderer>().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<Renderer>();
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方框

    /// <summary>/// 绘制Bounds方框/// </summary>/// <param name="bounds"></param>/// <param name="color"></param>/// <param name="offsetSize"></param>/// <param name="duration"></param>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

    /// <summary>/// 绘制boxCollider的绿色方框/// </summary>/// <param name="color"></param>void DrawGizmosOnRunTime(Color color){var boxCollider = GetComponent<BoxCollider>();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

    /// <summary>/// 绘制boxCollider的绿色方框/// </summary>/// <param name="boxCollider"></param>/// <param name="color"></param>/// <param name="offsetSize"></param>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<Renderer>();foreach (Renderer child in renders){center += child.bounds.center;   }center /= parent.GetComponentsInChildren<Transform>().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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_228638.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】图的实现

文章目录图1.图的基本概念2.图的存储结构3.邻接矩阵3.1邻接矩阵的优缺点3.2邻接矩阵的实现4.邻接表4.1邻接表的实现5.图的遍历5.1广度优先遍历5.2深度优先遍历5.3如何遍历不连通的图&#xff1f;图 1.图的基本概念 图是由顶点集合及顶点间的关系组成的一种数据结构&#xff1…

BERT-of-Theseus

最近了解到一种称为"BERT-of-Theseus"的BERT模型压缩方法&#xff0c;源自论文《BERT-of-Theseus: Compressing BERT by Progressive Module Replacing》。这是一种以"可替换性"为出发点所构建的模型压缩方案&#xff0c;相比常规的剪枝、蒸馏等手段&#…

streptavidin-PEG-6-FAM 链霉亲和素-聚乙二醇-6-羧甲基荧光素

产品名称&#xff1a;链霉亲和素-聚乙二醇-6-羧甲基荧光素 英文名称&#xff1a;streptavidin-PEG-6-FAM 纯度&#xff1a;95% 存储条件&#xff1a;-20C&#xff0c;避光&#xff0c;避湿 外观:固体或粘性液体&#xff0c;取决于分子量 PEG分子量可选&#xff1a;350、550、75…

自助建站工具

每用一次自助建站工具&#xff0c;就有一个程序员失业。 作为企业老板的你&#xff0c;要为公司的获客&#xff0c;企业推广发愁&#xff0c;但是预算有限&#xff0c;招人也很困难&#xff0c;不仅要面试程序员&#xff0c;后续还要检验这个程序员的功力&#xff0c;实在是太…

谷歌浏览器

引言&#xff1a;众所周知&#xff0c;一个好的浏览器可以提高我们的工作效率&#xff0c;那么今天教大家如何安装超 nice 的浏览器 —— 谷歌浏览器 文章目录一、安装谷歌浏览器二、修改谷歌浏览器搜索引擎三、修改谷歌浏览器默认下载位置一、安装谷歌浏览器 打开&#x1f5b…

GJB 5000B二级-II实施基础

本实践域为新增实践域   思想:以GJB5000A的共用过程域中不乏实践为基础进行提炼并提升,结合各个行业的优秀实践和行业特点,坚持问题导向,使标准更具有指导性和可操作性;充分借鉴GJB9001C中:“4组织环境”、“7支持”的相关内容,形成实施基础实践域。本实践域强调突出重…

0111 栈与队列Day1

剑指offer09.用两个栈实现队列 用两个栈实现一个队列。队列的声明如下&#xff0c;请实现它的两个函数 appendTail 和 deleteHead &#xff0c;分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素&#xff0c;deleteHead 操作返回 -1 ) 示例 1&#x…

Java ArrayLIst与顺序表

什么是集合类&#xff1f; Java当中的集合类&#xff0c;其实就是封装号的数据结构 原始的数据结构——>Java当中封装成的集合对应的那个原始的数据结构——>用Java封装的集合对应的。 集合类所在的包&#xff1a;java.util这个包底下 顺序表的底层是一个数组&#xff0…

结构力学常用公式表,早晚用得到!

来源&#xff1a;360个人图书馆 常用截面几何与力学特征表​​​​​​​ 注&#xff1a; I 称为截面对主轴&#xff08;形心轴&#xff09;的截面惯性矩 (mm4)。基本计算公式如下&#xff1a; W称为截面抵抗矩 (mm)&#xff0c;它表示截面抵抗弯曲变形能力的大小&#xff0c…

皕杰报表之隐藏处理

第一步&#xff0c;新建报表&#xff0c;然后新建参数 参数type设置成中文描述为统计类型、数据类型为字符串。 参数year设置成中文描述为年、数据类型为日期、时间日期格式为yyyy。 参数month设置成中文描述为月、数据类型为日期、时间日期格式为MM。 参数day设置成中文描…

python安全工具开发笔记(三)——python 多线程

一、Python线程和进程 进程 进程是程序的一次执行。每个进程都有自己的地址空间、内存、数据栈及其它记录其运行轨迹的辅助数据。 线程 所有的线程运行在同一个进程当中&#xff0c;共享相同的运行环境。线程有开始顺序执行和结束三个部分。 帮助理解&#xff1a; 1、计算…

VM系列振弦采集模块传感器激励方法

VM系列振弦采集模块传感器激励方法 通过修改寄存器 EX_METH.[3:0]来完成激励方法的选择&#xff0c; EX_METH[4]用于设置是否忽略传感器的接入检测而强制发送激励信号。 高压脉冲激励法 高压脉冲激励法 HPM&#xff08; High Voltage Pulse Excitation Method&#xff09;。 向…

桌面画图工具:Pointofix(fertig)

Pointofix桌面画图工具 Pointofix - der virtuelle Textmarker fr Ihren Bildschirm - Freeware 一、软件下载 官方网址https://www.pointofix.de/ 二、进入下载页面&#xff0c;需要下载安装文件和语言包两个文件 三、网站还提供了一个语言设置小程序&#xff0c;但我没用 …

教师如何创建百度百科词条?这篇带你了解

互联网时代&#xff0c;如果你是小有名气的人物&#xff0c;或是某个领域的专家&#xff0c;对于社会有一定的贡献或是影响力&#xff0c;就可以在百度上搜到一个你的专属词条。 百度百科词条就是个人的一张网络名片&#xff0c;人物的一些基本信息、生平事迹、代表作品、所获…

mac下安装nodejs跟vscode

1.打开官网 Node.js 2.点击下载 3.下载完成&#xff0c;根据提示下一步安装&#xff0c;安装完成后&#xff0c;在vscode中新建一个js文件&#xff0c;执行node test.js

基于STM32单片机的篮球计时记分器proteus仿真原理图PCB

功能&#xff1a; 0.本系统采用STC89C52作为单片机 1.LCD1602液晶实时显示比赛剩余时间&#xff0c;球队分数 2.默认计时器为4节&#xff0c;每节10分钟&#xff0c;每节比赛结束&#xff0c;蜂鸣器报警 3.按键功能介绍: 1’键——加1分 4’键——减1分 2’键——加2分 5’键—…

[附源码]计算机毕业设计springboot人体健康管理app

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

静态路由配置案例

静态路由配置案例配置静态路由原理命令&#xff1a;案例&#xff1a;最后结果&#xff1a;配置静态路由原理命令&#xff1a; [Huawei]ip route-static 来源ip 子网掩码 去向ip [Huawei]ip route-static 192.168.20.1 255.255.255.0 192.168.1.2 案例&#xff1a; pc1,pc2,a…

MySQL数据库实现主从复制,docker实现版

我这里是在同一台电脑上使用docker实现的主从复制&#xff0c;在物理机上整体思路是一致的 预备工作&#xff1a;安装好docker 使用docker运行MySQL 拉取MySQL镜像 docker pull mysql:5.7运行mysql master容器 sudo docker run -p 33061:3306 --name mysql-master-v /myda…

Docker with IPV6

1、绪论 在 Docker 容器或群服务中使用 IPv6 之前&#xff0c;您需要在 Docker 守护进程中启用 IPv6 支持。之后&#xff0c;您可以选择对任何容器、服务或网络使用 IPv4 或 IPv6&#xff08;或两者&#xff09; 2、配置默认 Docker IPv6 注意&#xff1a;IPv6 网络仅在 Lin…