Unity Bound详解

这篇具有很好参考价值的文章主要介绍了Unity Bound详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

内容将会持续更新,有错误的地方欢迎指正,谢谢!
 

Unity Bound详解
     
TechX 坚持将创新的科技带给世界!

拥有更好的学习体验 —— 不断努力,不断进步,不断探索
TechX —— 心探索、心进取!

助力快速掌握 Bounds

为初学者节省宝贵的学习时间,避免困惑!


unity bounds,Unity知识点,unity,游戏引擎



一、Bounds概述

1、Bounds类型


在 Unity 中,包围盒(Bounding Box)是一个几何形状,用于近似地表示物体或一组物体在三维空间中的范围或边界。它是一个简单的形状,通常是立方体或矩形,完全包围了一个物体或一组物体。

包围盒有多种类型,包括:

  • AABB(Axis-Aligned Bounding Box,轴对齐包围盒): 这是一种以坐标轴为方向的包围盒,其六个面都与坐标轴平行。AABB 在处理物体的碰撞检测、物体的可见性检查和简单的物体包围优化方面非常高效。

  • OBB(Oriented Bounding Box,方向包围盒): 这是一种可以沿着物体的方向进行旋转的包围盒。与 AABB 不同,OBB 可以根据物体的朝向而自由旋转,因此更精确地包围了物体,但计算量也更大。

  • Sphere Bounds(球形包围盒): 这是一个包围物体的球体,通常用于物体的碰撞检测或可见性检查。对于不规则形状的物体,球形包围盒可能不是最精确的表示,但它提供了一种简单和快速的碰撞检测方法。

2、Bounds属性


在 Unity 中,许多对象都有一个 Bounds 属性,用于描述该对象的包围盒。例如,Renderer、Collider 和 Mesh 等组件都具有 Bounds 属性,这些属性用于表示对象或物体的包围盒。Bounds 的属性通常包括包围盒的中心点位置和尺寸。

unity bounds,Unity知识点,unity,游戏引擎

size 包围盒的尺寸,它描述了包围盒在三个轴(X、Y 和 Z 轴)方向上的宽度、高度和深度。
center 包围盒的中心点位置,这个中心点是包围盒所囊括的对象或物体的几何中心。
extents 表示是 size 属性的一半,它表示包围盒在每个轴上的正向半尺寸。
min (世界坐标)边界盒的最小点,这个值总是等于center-extents。
max (世界坐标)边界盒的最大点,这个值总是等于center+extents。
ClosestPoint(Vector3 point) 用于找到包围盒上离给定点最近的点。传入一个点的 Vector3 坐标,返回包围盒上距离该点最近的点的坐标。
Contains(Vector3 point) 检查一个点是否在包围盒内部。传入一个 Vector3 坐标表示的点,如果点在包围盒内部,返回 true;否则返回 false。
Encapsulate(Bounds bounds) 用于扩展包围盒以包含另一个 Bounds 对象。传入一个 Bounds 对象,该方法会调整当前包围盒,使其完全包含传入的 Bounds 对象。
Encapsulate(Vector3 point) 用于扩展包围盒,使其包括给定点。传入一个点的 Vector3 坐标,这个点将被包围盒完全包含。
SetMinMax(Vector3 min, Vector3 max) 根据最小和最大顶点的坐标来设置包围盒。传入最小和最大顶点的坐标 Vector3 值,以重新定义包围盒的位置和大小。
Expand(float amount) 通过在每个轴上扩展包围盒的尺寸来调整包围盒的大小。传入一个浮点数 amount,这个值将分别添加到包围盒的宽度、高度和深度上。

二、Unity中的Bounds

1、Renderer Bounds(渲染器包围盒)


Renderer(渲染器)是将图形渲染到屏幕上的组件。每个 Renderer 都有一个 Bounds 属性,该属性表示该渲染器所渲染内容的包围盒。该包围盒由该 Renderer 下所有渲染的网格(Mesh)的合并包围而成。通常用于确定对象的可见性以进行相机裁剪。

绘制Renderer Bounds:

public class MyComponent : MonoBehaviour
{
	//Renderer Bounds为世界坐标
    private Bounds bounds;
	private MeshRenderer renderer;

    void OnDrawGizmos()
    {
        // 获取物体的 MeshRenderer 组件
        renderer = GetComponent<MeshRenderer>();
        bounds = renderer.bounds;
        
        // 设置 Gizmos 的颜色
        Gizmos.color = Color.green;
        Gizmos.DrawWireCube(bounds.center, bounds.size);
    }
}
  • 位移对 Render Bounds 的影响:

当物体发生位移时,渲染器的 Bounds 将会相应地跟随物体的移动而更新。此时,渲染器的 Bounds 也会随之移动,以确保正确的可见性计算。

unity bounds,Unity知识点,unity,游戏引擎

  • 旋转对 Render Bounds 的影响:

当物体发生旋转时,渲染器的 Bounds 将会进行相应的更新。与位移不同,旋转会导致包围盒的大小发生变化,但是并不会随着物体的旋转而旋转。

unity bounds,Unity知识点,unity,游戏引擎

  • 缩放对 Render Bounds 的影响:

当物体发生缩放时,渲染器的 Bounds 将根据缩放而相应地进行更新,此时,渲染器的 Bounds 也会随之缩放,以确保正确的包围盒。

unity bounds,Unity知识点,unity,游戏引擎

2、Collider Bounds(碰撞器包围盒)


Collider(碰撞器)是用于检测碰撞的组件。各种类型的碰撞器(如 BoxCollider、SphereCollider 等)都有一个 Bounds 属性,表示碰撞器的包围盒。这个包围盒用于计算碰撞,触发碰撞事件或进行物理模拟。

绘制Collider Bounds:

public class MyComponent : MonoBehaviour
{
	//Collider Bounds为世界坐标
    private Bounds bounds;
	private BoxCollider boxCollider;

    void OnDrawGizmos()
    {
         //获取物体的 BoxCollider组件
         boxCollider = GetComponent<BoxCollider>();
         bounds = boxCollider.bounds;
        
        // 设置 Gizmos 的颜色
        Gizmos.color = Color.green;
        Gizmos.DrawWireCube(bounds.center, bounds.size);
    }
}
  • 位移对 Collider Bounds 的影响:

当物体发生位移时,渲染器的 Bounds 将会相应地跟随物体的移动而更新。此时,渲染器的 Bounds 也会随之移动,以确保正确的可见性计算。

unity bounds,Unity知识点,unity,游戏引擎

  • 旋转对 Collider Bounds 的影响:

当物体发生旋转时,渲染器的 Bounds 将会进行相应的更新。与位移不同,旋转会导致包围盒的大小发生变化,但是并不会随着物体的旋转而旋转。

unity bounds,Unity知识点,unity,游戏引擎

  • 缩放对 Collider Bounds 的影响:

当物体发生缩放时,渲染器的 Bounds 将根据缩放而相应地进行更新,此时,渲染器的 Bounds 也会随之缩放,以确保正确的包围盒。

unity bounds,Unity知识点,unity,游戏引擎

3、Mesh Bounds(网格包围盒)


Mesh 是表示三维对象表面的集合,而 MeshRenderer 用于渲染这些 Mesh。每个 Mesh 也有一个 Bounds 属性,表示该网格的包围盒。这个包围盒通常是由网格的顶点位置计算得出的最小包围盒,用于优化渲染和碰撞检测。

绘制Mesh Bounds:

public class MyComponent : MonoBehaviour
{
	//Mesh Bounds为本地坐标
    private Bounds bounds;
	private MeshFilter filter ;

    void OnDrawGizmos()
    {
          获取物体的 MeshFilter组件
         MeshFilter filter = GetComponent<MeshFilter>();
         bounds = filter.sharedMesh.bounds;
         //将本地坐标转换未为世界坐标
         var centerPoint = transform.TransformPoint(bounds.center);
         bounds = new Bounds(centerPoint, bounds.size);
        
        // 设置 Gizmos 的颜色
        Gizmos.color = Color.green;
        Gizmos.DrawWireCube(bounds.center, bounds.size);
    }
}
  • 位移对 Mesh Bounds 的影响:

当物体发生位移时,渲染器的 Bounds 将会相应地跟随物体的移动而更新。此时,渲染器的 Bounds 也会随之移动,以确保正确的可见性计算。

unity bounds,Unity知识点,unity,游戏引擎

  • 旋转对 Collider Bounds 的影响:
  • 缩放对 Collider Bounds 的影响:

Mesh 的 Bounds 是在创建 Mesh 时根据其顶点位置计算得出的最小包围盒。这个包围盒通常在创建 Mesh 时就已经固定,并不会随着对象的缩放或旋转而实时更新。

所以,当对物体进行缩放或旋转时,Mesh Bounds 并不会实时更新以适应这些变化。即使缩放或旋转了对象,Mesh Bounds 也仍然保持着原始计算得出的包围盒形状和大小。

unity bounds,Unity知识点,unity,游戏引擎
unity bounds,Unity知识点,unity,游戏引擎

三、Bounds和Collider 的区别


  • Collider 中的包围盒(OBB):

Collider 组件通常根据对象的形状来创建相应的碰撞区域(例如,BoxCollider、SphereCollider 等)。这些 Collider 使用的包围盒通常是有向包围盒(OBB),也就是说,它们可以随着对象的旋转而旋转,并根据对象的形状而形成相应的碰撞区域。

OBB 提供了更好的检测精度,因为它可以更好地适应对象的形状和旋转。

public class MyComponent : MonoBehaviour
{
	private BoxCollider boxCollider;

    void OnDrawGizmos()
    {
         //获取物体的 BoxCollider组件
         boxCollider = GetComponent<BoxCollider>();
         
         // 设置 Gizmos 的颜色
         Gizmos.color = Color.green;
         Matrix4x4 rotationMatrix = Matrix4x4.TRS(transform.position, transform.rotation, transform.lossyScale);
         // 根据物体的变换,绘制实时的 Bounds
         Matrix4x4 oldMatrix = Gizmos.matrix;
         Gizmos.matrix = rotationMatrix;
         Gizmos.DrawWireCube(boxCollider.center, boxCollider.size);
         Gizmos.matrix = oldMatrix;
    }
}
  • Bounds 中的包围盒(AABB):

Bounds 包围盒通常是无向包围盒(AABB)。这意味着它不会随着对象的旋转而旋转,而是始终保持沿着坐标轴的方向。

AABB 通常用于快速包围物体,但在对象旋转时可能无法准确地包裹对象的形状,因为它是固定的沿坐标轴的边界框。文章来源地址https://www.toymoban.com/news/detail-825573.html


四、Bounds的相关计算

1、计算Bounds顶点

/// <summary> Bounds顶点 </summary>
/// <param name="bounds"></param>
public Vector3[] DrawBoundBoxLine(Bounds bounds)
{
    //计算出包围盒8个点
    Vector3 min = bounds.min;
    Vector3 max = bounds.max;
    Vector3[] vertices = new Vector3[8];

    // 计算八个顶点的坐标
    vertices[0] = new Vector3(min.x, min.y, min.z);
    vertices[1] = new Vector3(max.x, min.y, min.z);
    vertices[2] = new Vector3(min.x, min.y, max.z);
    vertices[3] = new Vector3(max.x, min.y, max.z);
    vertices[4] = new Vector3(min.x, max.y, min.z);
    vertices[5] = new Vector3(max.x, max.y, min.z);
    vertices[6] = new Vector3(min.x, max.y, max.z);
    vertices[7] = new Vector3(max.x, max.y, max.z);
	return vertices;
}

2、扩展多个Bounds

public class MyComponent : MonoBehaviour
{
	private Bounds bounds;
	
	/// <summary> 扩展Bounds </summary>
	/// <param name="model"></param>
	public Bounds ExtendBound(Transform model)
	{
		Vector3 center = Vector3.zero;
		Renderer[] renders = model.GetComponentsInChildren<Renderer>();
		
		foreach (Renderer child in renders){
			center += child.bounds.center;   
		}
		
		center /= model.GetComponentsInChildren<Transform>().Length; 
		Bounds bounds = new Bounds(center,Vector3.zero);
		
		foreach (Renderer child in renders)
		{
			bounds.Encapsulate(child.bounds);   
		}
		return bounds;
	}
	
	void OnDrawGizmos()
	{
	    bounds = ExtendBound(transform);
	     设置 Gizmos 的颜色
	    Gizmos.color = Color.green;
	    Gizmos.DrawWireCube(bounds.center, bounds.size);
	}
}




TechX —— 心探索、心进取!

每一次跌倒都是一次成长

每一次努力都是一次进步

END
感谢您阅读本篇博客!希望这篇内容对您有所帮助。如果您有任何问题或意见,或者想要了解更多关于本主题的信息,欢迎在评论区留言与我交流。我会非常乐意与大家讨论和分享更多有趣的内容。
如果您喜欢本博客,请点赞和分享给更多的朋友,让更多人受益。同时,您也可以关注我的博客,以便及时获取最新的更新和文章。
在未来的写作中,我将继续努力,分享更多有趣、实用的内容。再次感谢大家的支持和鼓励,期待与您在下一篇博客再见!

到了这里,关于Unity Bound详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Unity知识点 -- AssetBundle(AB包)

    特定于平台的资产压缩包,类似于压缩文件 资产包括:模型、贴图、预制体、音效、材质球等 2.1 相对于 Resources 下的资源,AB 包更好管理资源 Resource:打包时定死,只读,无法修改 AB包:存储位置可以自定义,压缩方式可以自定义,后期可以动态更新,通过 AB 包可以做热更

    2024年02月13日
    浏览(45)
  • Unity3D知识点精华浓缩

    一、细节 1、类与组件的关系 2、Time.deltaTime的含义 3、怎么表示一帧的移动距离 4、Update和LateUpdate的区别和适用场景 5、找游戏对象的方式(别的对象 / 当前对象的子对象) 6、组件1调用组件2中方法的方式 7、在面板中获取外部数据的方法 8、序列化属性、序列化自定义对象的

    2024年04月09日
    浏览(39)
  • 【unity数据持久化】XML数据管理器知识点

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 :Unity基础实战 XML是什么 XML(Extensible Markup Language)是一种类似于 HTML,但是没有使用预定义标记的语言。因此,可以根据自己的设计需求

    2024年02月11日
    浏览(42)
  • 【新】Unity Meta Quest MR 开发(二):场景理解 Scene API 知识点

    此教程相关的详细教案,文档,思维导图和工程文件会放入 Spatial XR 社区 。这是一个高质量 XR 社区,博主目前在内担任 XR 开发的讲师。此外,该社区提供教程答疑、及时交流、进阶教程、外包、行业动态等服务。 社区链接: Spatial XR 高级社区(知识星球) Spatial XR 高级社区

    2024年01月25日
    浏览(42)
  • [Lua][Love] 打砖块游戏实现过程与知识点

    本文旨在根据LOVE2D官方文档和教程实现打砖块的游戏,记录部分实现过程和重要知识点 目标摧毁所有砖块 玩家控制球拍左右滑动反弹小球 小球摧毁砖块 小球保持在屏幕内 小球碰到屏幕底部,GAME OVER 在加载引擎的时候回调该函数修改引擎基本参数,默认参数可看Config Files

    2024年02月11日
    浏览(43)
  • [Lua][Love Engine] 打砖块游戏实现过程与知识点

    本文旨在根据LOVE2D官方文档和教程实现打砖块的游戏,记录部分实现过程和重要知识点 目标摧毁所有砖块 玩家控制球拍左右滑动反弹小球 小球摧毁砖块 小球保持在屏幕内 小球碰到屏幕底部,GAME OVER 在加载引擎的时候回调该函数修改引擎基本参数,默认参数可看Config Files

    2024年02月12日
    浏览(35)
  • pgzero所有知识点详解

    目录  什么是pgzero? pgzero的安装 4,正式开始! 1,调整背景色 2,导入角色 3,鼠标事件 5,按键事件 6,刷新功能 1,角色属性 2,功能介绍 7,全局变量and局部变量 1,全局变量与局部变量的区别 2,全局变量如何在功能内使用 8,角色功能及窗口功能 1,角色功能 2,窗口功

    2024年02月05日
    浏览(42)
  • 详解MVCC相关知识点

    前言:学习前,先叙述mysql相关基础知识,一步步了解mysql底层机制。 数据库事务的隔离级别有4个,由低到高依次为Read uncommitted 、Read committed、Repeatable read 、Serializable ,这四个级别可以逐个解决脏读 、不可重复读 、幻读 这几类问题。 √: 可能出现    ×: 不会出现

    2024年02月06日
    浏览(43)
  • Spring AOP知识点详解

    Spring AOP是 Spring最核心的能力,那到底什么是AOP呢,今天了不起带大家了解一下。 AOP(Aspect Oriented Programming): 面向切面编程 ,是OOP(面向对象编程)的一个延续,其和OOP一样,也是一种编程思想,不过AOP是一种横向开发模式。 OOP ,面向对象,允许开发者定义纵向的关系,但并适

    2024年02月16日
    浏览(58)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包