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

这篇具有很好参考价值的文章主要介绍了Unity3d bounds包围盒 和collider碰撞器区别。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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);

碰撞器绿方框

collider.bounds,unity3d,unity3d,c#

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

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

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

下面红色方框就是 Bounds 方框

collider.bounds,unity3d,unity3d,c#

Bounds属性

只读属性

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

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

collider.bounds,unity3d,unity3d,c#

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);
}

collider.bounds,unity3d,unity3d,c#
 

计算包围盒的八个顶点

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

collider.bounds,unity3d,unity3d,c#

 collider.bounds,unity3d,unity3d,c#

绘制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

collider.bounds,unity3d,unity3d,c#

 计算所有包围盒的中心点

计算出多个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文章来源地址https://www.toymoban.com/news/detail-783057.html

到了这里,关于Unity3d bounds包围盒 和collider碰撞器区别的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity3d 物体不动,碰撞触发不了的情况

    问题: 有一种情况,主角带刚体,主角站着不动。玩家站在陷阱上,陷阱的碰撞体 Toggle 之后, OnCollisionEnter 触发不了。 解决:盲猜玩家组件上才有刚体,而碰撞检测是刚体运动的时候,才进行检测的。

    2024年02月06日
    浏览(63)
  • unity3d,平面和四边形的区别是什么

    在Unity中,平面和四边形都是基础的几何形状,用于创建游戏场景中的地形、墙壁、天花板等。虽然它们都是由多个点和线构成的,但是它们之间有着一些重要的区别。 平面是由三个或更多个点组成的,这些点通常位于同一平面上。在Unity中,可以使用Mesh类来创建平面,并指

    2024年02月03日
    浏览(40)
  • UE虚幻引擎,Unity3D,Blender区别和联系

    Unity UE Blender Unity 用户手册 (2019.4 LTS) - Unity 手册 虚幻引擎5.2文档 | 虚幻引擎5.2文档 (unrealengine.com) Blender 3.5 Reference Manual — Blender Manual Blender 是一款免费的开源软件,是一个开源的三维建模和动画软件 Blender: Design and animation platform which assists organizations of all sizes with rendering,

    2024年02月12日
    浏览(43)
  • 【Unity3D日常开发】Unity3D中协程的使用

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 大家好,我是佛系工程师 ☆恬静的小魔龙☆ ,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 最近有小伙伴问协程怎么用、怎么写,我也是会用会写,但是原理不是很明白。 学习了一下,总结出

    2024年02月12日
    浏览(58)
  • unity3D基础操作之01--unity3d窗口界面介绍

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 1、Scene场景编辑窗口; 2、Game游戏运行窗口; 3、Hierarchy场景物体列表窗口; 4、Project项目资源列表窗口; 5、Inspector属性编辑列表窗口; 6、其他常调节窗口 在屏幕左上方为场景编辑窗口Scene,在场景编

    2024年02月06日
    浏览(80)
  • 【Unity3D小功能】Unity3D中实现Text显示版本功能

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 大家好,我是佛系工程师 ☆恬静的小魔龙☆ ,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 在项目开发中,会遇到要控制版本的情况,比如说对比版本号,版本不对再更新版本的功能,这些就是

    2024年02月05日
    浏览(76)
  • 【Unity3D-01】 记录Unity3D调用外接摄像头

    最近想在Unity3D上调用一个摄像头,通过查找资料发现仙魁XAN和八哥快走开的博客符合我的想法,实现起来也不难就尝试了一下 2.1 在这个工程里新建Canvas 如下图所示 然后下设RawImage为载体 2.2 在Assets里面新建一个脚本命名为PlaneManager.cs 代码内容如下(参考八哥快走开的博客)

    2024年02月04日
    浏览(54)
  • 【Unity3D日常开发】Unity3D中实现单例模式详解

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 大家好,我是佛系工程师 ☆恬静的小魔龙☆ ,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 首先,说一下,什么是 单例模式(Singleton) 。 单例模式是设计模式中常见的一种设计模式,目的是为了

    2024年02月02日
    浏览(65)
  • 【Unity3D小功能】Unity3D中实现点击‘文字’出现‘UI面板’

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 QQ群:398291828 大家好,我是佛系工程师 ☆恬静的小魔龙☆ ,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 宠粉博主又来了,今天有粉丝问我如何实现点击一段文字然后出现的面板在那段文字附近显示: 深入了

    2024年04月13日
    浏览(83)
  • 【Unity3D】Unity3D 软件安装 ( 注册账号并下载 Unity Hub | 安装 Unity Hub | 获取个人版授权 | 中文环境设置 | 安装 Unity3D 编辑器 )

    Unity 官方网站 : 英文 : https://unity.com 中文 : https://unity.cn 进入 中文网站 https://unity.cn , 点击右上角的 \\\" 下载 Unity \\\" 按钮 ; 推荐下载 Unity3D 的长期支持版本 ; 点击界面中的 \\\" 下载 Unity Hub \\\" 选项 ; 根据你的系统 , 选择对应的 Unity Hub , 我在 Windows 上开发 , 因此选择 \\\" Windows 下载 \\\"

    2024年01月25日
    浏览(100)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包