Unity入门7——物理系统之碰撞检测

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

一、刚体 Rigid Body

​ 刚体利用体积(碰撞器 Collider)进行碰撞计算,模拟真实的碰撞效果,产生力的作用

Unity入门7——物理系统之碰撞检测

​ 碰撞产生的必要条件:

  • 两个物体都有碰撞器 Collider
  • 至少一个物体有刚体
  1. Mass:质量

    默认为千克,质量越大惯性越大

  2. Drag:空气阻力

    根据力移动对象时影响空气阻力大小

    0 表示没有空气阻力

  3. Augular Drag:旋转阻力

    根据扭矩旋转对象时影响对象的空气阻力大小

    0 表示没有阻力

  4. Use Gravity:是否受重力影响

  5. Is Kinematic:是否设置为运动学

    如果启用,对象将不会被物理引擎驱动,只能通过 Transform 对其进行操作

    对于移动平台,或者如果要动画附加了 HingeJoint 的刚体,此属性将非常有用

  6. Interpolate:插值运算

    • None:不应用插值运算

    • Interpolate:根据前一帧的变换来平滑变换

    • Extrapolate:插值运算

      根据下一帧的估计变换来平滑变换,若物理帧时间过长,此效果将不好

  7. Collison Detection:碰撞检测模式

    • Discrete:离散检测

      对场景中的所有其他碰撞体使用离散碰撞检测,其他碰撞体在测试碰撞时会使用离散检测。

      用于正常碰撞(默认值)

    • Continuous:连续检测

      对动态碰撞体(具有刚体)使用离散碰撞检测

      对静态碰撞体(没有刚体)使用连续碰撞检测

      设置为连续动态的刚体,将在测试与该刚体的碰撞时使用连续碰撞检测(物理性能消耗较大,物体运动缓慢时请设置为 Discrete)

      其他刚体将使用离散碰撞检测

    • Continuous Dynamic:连续动态检测

      对设置为连续和连续动态碰撞的对象使用连续碰撞检测

      对静态碰撞体(没有刚体)使用连续碰撞检测

      对其他碰撞体使用离散碰撞检测

      用于快速移动的对象

    • Continuous Speculative:连续推测检测

      对刚体和碰撞体使用推测性连续碰撞检测

      通常比连续碰撞检测的成本更低

    无刚体碰撞盒 Discrete Continuous Continuous Dynamic Continuous Speculative
    无刚体碰撞盒 不检测碰撞 Discrete Continuous Continuous Continuous Speculative
    Discrete Discrete Discrete Discrete Discrete Continuous Speculative
    Continuous Continuous Discrete Discrete Continuous Continuous Speculative
    Continuous Dynamic Continuous Discrete Continuous Continuous Continuous Speculative
    Continuous Speculative Continuous Speculative Continuous Speculative Continuous Speculative Continuous Speculative Continuous Speculative
    显示详细信息

    性能消耗关系:Continuous Dynamic > Continuous Speculative > Continuous > Discrete

  8. Constrains:对刚体运动的约束

    • Freeze Position:限制刚体在世界坐标轴下 X、Y、Z 轴的移动
    • Freeze Rotation:限制刚体在世界坐标轴下 X、Y、Z 轴的旋转
  9. Info:用于显示参数的面板,不修改里面的值

二、碰撞器 Collider

​ 碰撞器表示物体的体积(形状)

​ 碰撞器种类一共有 6 种:

  • 盒状碰撞器 Box Collider
  • 球状碰撞器 Sphere Collider
  • 胶囊碰撞器 Capsule Collider
  • 网格碰撞器 Mesh Collider
  • 轮胎碰撞器 Wheel Collider
  • 地形碰撞器 Terrain Collider

​ 常用的为前 3 种

(一)共同参数

  1. Edit Collider:编辑碰撞器的大小

  2. Is Trigger:是否为触发器

    如果启用,则该碰撞体用于触发事件,并被物理引擎所忽略

    主要用于进行没有物理效果的碰撞检测

  3. Material:物理材质

    可以确定碰撞体和其他对象碰撞时的交互(表现)方式

  4. Center:碰撞体的中心偏移位置

(二)常用碰撞器

  1. Box Collider
    • Size:碰撞体在 X、Y、Z 方向上的大小
  2. Sphere Collider
    • Radius:球形碰撞体的半径大小
  3. Capsule Collider
    • Radius:胶囊体的半径
    • Height:胶囊体的高度
    • Direction:胶囊体在对象局部空间中的轴向

(三)异形物体使用多种碰撞器组合

​ 刚体对象的子对象碰撞信息参与碰撞检测

​ 即父物体添加 Rigid Body,子物体设置 Collider。

(四)不常用碰撞器

  1. Mesh Collider

    • Convex:是否为凸面的

      勾选后,该 Mesh Collider 将会与其他 Mesh Collider 发生碰撞,最多支持 255 个三角面片

      如果该对象添加了刚体 Rigid Body,则该选项必须勾选,否则会报错

    • Cooking Options:物理引擎对网格的处理方式

      不常用

    • Mesh:引用需要用于碰撞的网格

  2. Wheel Collider

    赛车游戏中使用,其他时候不常用

    注意:添加 Wheel Collider 后一定要添加 Rigid Body(或在父物体添加),否则将失效

  3. Terrain Collider

    地形系统中使用

    性能较为低下,很少使用

三、物理材质

​ 在 Project 中创建物理材质 Physics Material

Unity入门7——物理系统之碰撞检测
Unity入门7——物理系统之碰撞检测

  1. Dynamic Friction:滑动摩擦力

    0 表示绝对光滑,1 表示迅速静止

  2. Static Frction:静摩擦力

    0 表示绝对光滑,1 表示无法移动

  3. Bounciness:表面弹性

    0 表示不会反弹,1 表示反弹没有能量损失,甚至可能会增加少量能量

  4. Friction Combine:摩擦力组合方式

    • Average:取平均值
    • Minimum:取最小值
    • Maximum:取最大值
    • Multiply:相乘
  5. Bounce Combine:弹性组合方式

    • Average:取平均值
    • Minimum:取最小值
    • Maximum:取最大值
    • Multiply:相乘

四、碰撞检测函数

​ 碰撞和触发响应函数属于特殊的生命周期函数,也是通过反射调用

​ 碰撞和触发器函数都可以写成虚函数,在子类去重写逻辑

Unity入门7——物理系统之碰撞检测

(一)物理碰撞检测响应函数

// 碰撞触发接触时会 自动执行这个函数
private void OnCollisionEnter(Collision collision)
{
    // Collision类型的 参数 包含了 碰到自己的对象的相关信息

    // 关键参数
    // 1.碰撞到的对象碰撞器的信息
    collision.collider

    // 2.碰撞对象的依附对象(GameObject)
    collision.gameObject

    // 3.碰撞对象的依附对象的位置信息
    collision.transform

    // 4.触碰点数相关
    collision.contactCount
    // 接触点 具体的坐标
    ContactPoint[] pos = collision.contacts;

    // 只要得到了 碰撞到的对象的 任意一个信息 就可以得到它的所有信息

    print(this.name + "被" + collision.gameObject.name + "撞到了");
}

// 碰撞结束分离时  会自动执行的函数
private void OnCollisionExit(Collision collision)
{
    print(this.name + "被" + collision.gameObject.name + "结束碰撞了");
}

// 两个物体相互接触摩擦时 会不停的调用该函数
private void OnCollisionStay(Collision collision)
{
    print(this.name + "一直在和" + collision.gameObject.name + "接触");
}

(二)触发器检测响应函数

// 触发开始的函数 当第一次接触时 会自动调用
protected virtual void OnTriggerEnter(Collider other)
{
    print(this.name + "被" + other.gameObject.name + "触发了");
}

// 触发结束的函数 当水乳相融的状态结束时 会调用一次
private void OnTriggerExit(Collider other)
{
    print(this.name + "被" + other.gameObject.name + "结束水乳相融的状态了");
}

// 当两个对象 水乳相融的时候 会不停调用
private void OnTriggerStay(Collider other)
{
    print(this.name + "和" + other.gameObject.name + "正在水乳相融");
}
  1. 只要挂载的对象能和别的物体产生碰撞或者触发,那么对应的这 6 个函数就能够被响应

  2. 6 个函数不是说都得写,一般根据需求来进行选择书写,一般用 Enter 函数较多

  3. 如果是一个异形物体,刚体在父对象上,如果你想通过子对象上挂脚本检测碰撞是不行的,必须挂载到这个刚体父对象上才行

五、刚体加力

(一)刚体自带添加力的方法

  1. 获取刚体组件
rigidBody = this.GetComponent<Rigidbody>();
  • 1
  1. 添加力
// 相对世界坐标
// 世界坐标系 Z轴正方向加了一个力
// 加力过后 对象是否停止移动 是由阻力决定的
// 如果阻力为0 那给了一个力过后 始终 是不会停止运动
rigidBody.AddForce(Vector3.forward * 10);

// 如果想要在 世界坐标系方法中 让对象 相对于自己的面朝向动
rigidBody.AddForce(this.transform.forward * 10);

// 相对本地坐标
rigidBody.AddRelativeForce(Vector3.forward * 10);

//如果你希望即使有阻力 也希望对象一直动 那你就把下面代码放在Update函数中 一直“推”就行了
rigidBody.AddForce(Vector3.forward * 10);
  1. 添加扭矩力
// 相对世界坐标
// 绕y轴旋转
rigidBody.AddTorque(Vector3.up * 10);

// 相对本地坐标
rigidBody.AddRelativeTorque(Vector3.up * 10);
  1. 直接改变速度
// 这个速度方向 是相对于 世界坐标系的 
// 如果要直接通过改变速度 来让其移动 一定要注意这一点
rigidBody.velocity = Vector3.forward * 5;
  1. 模拟爆炸效果
// 模拟爆炸的力 一定是 所有希望产生爆炸效果影响的对象 
// 都需要得到他们的刚体 来执行这个方法 才能都有效果
// 参数一 爆炸力
// 参数二 爆炸位置
// 参数三 爆炸半径范围
rigidBody.AddExplosionForce(100, Vector3.zero, 10);

(二)力的模式

// 第二个参数 力的模式 主要的作用 就是 计算方式不同而已 
// 由于4中计算方式的不同 最终的移动速度就会不同
rigidBody.AddForce(Vector3.forward * 10, ForceMode.Acceleration);

​ 速度计算公式:v = F * t / m(动量定理)

  1. Acceleration

    给物体增加一个持续的加速度,忽略其质量

    F = (0, 0, 10)、t = 0.02 s、m = 默认为 1
    v = 10 * 0.02 / 1 = 0.2 m/s
    每物理帧移动 0.2 m/s * 0.02 = 0.004 m

  2. Force

    给物体添加一个持续的力,与物体的质量有关
    F = (0, 0, 10)、t = 0.02 s、m = 2 kg
    v = 10 * 0.02 / 2 = 0.1 m/s
    每物理帧移动 0.1 m/s * 0.02 = 0.002 m

  3. Impulse

    给物体添加一个瞬间的力,与物体的质量有关,忽略时间,t 默认为1
    F = (0, 0, 10)、t = 1 s、m = 2 kg
    v = 10 * 1 / 2 = 5 m/s
    每物理帧移动 5 m/s * 0.02 = 0.1 m

  4. VelocityChange

    给物体添加一个瞬时速度,忽略质量,忽略时间
    F = (0, 0, 10)、t = 1 s、m = 默认为 1
    v = 10 * 1 / 1 = 10 m/s
    每物理帧移动 10 m/s * 0.02 = 0.2 m

(三)力场

​ 为物体添加 Constant Force,若物体之前没有 Rigid Body,则会为其自动添加

Unity入门7——物理系统之碰撞检测

​ 进行参数设置

Unity入门7——物理系统之碰撞检测

(四)刚体休眠

​ Unity 为了节约性能,为刚体添加了休眠机制:

Rigidbody sleeping happens completely automatically. Whenever a rigidbody is slower than the sleepAngularVelocity and sleepVelocity it will start falling asleep. After a few frames of resting it will then be set to sleep. When the body is sleeping, no collision detection or simulation will be performed anymore. This saves a lot of CPU cycles.

刚体休眠完全自动发生。只要刚体的速度低于 sleepAngularVelocity 和 sleepVelocity,该刚体就会开始休眠。其空闲一些帧后,就会被设置成休眠状态。处于休眠状态中的物体,不会再对其进行碰撞检测和模拟。这会节约大量的 CPU 开销。

​ 例如,在为 Cube 添加 Rigid Body 后其下落静止在平面上

Unity入门7——物理系统之碰撞检测

​ 将平面旋转一定角度后,发现 Cube 悬空,说明此时 Cube 的刚体休眠了

Unity入门7——物理系统之碰撞检测

​ 将平面向下以一定速度拖动,则 Cube 下落,刚体被激活

Unity入门7——物理系统之碰撞检测

​ 使用代码控制:文章来源地址https://www.toymoban.com/news/detail-486674.html

// 获取刚体是否处于休眠状态 如果是 
if (rigidBody.IsSleeping())
{
    // 就唤醒它
    rigidBody.WakeUp();
}

到了这里,关于Unity入门7——物理系统之碰撞检测的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 基于ssm手机商城管理系统(源码+开题)

    本系统(程序 + 源码)带文档 lw 万字以上 文末可获取一份本项目的 java 源码和数据库参考。 研究背景: 随着移动互联网的快速发展,手机商城成为人们购物的重要渠道。传统的手机商城管理方式存在着信息不透明、效率低下等问题。因此,开发一款基于SSM框架的手机商城管

    2024年01月21日
    浏览(88)
  • 工单管理系统有什么作用?如何告别“走流程式”巡检!

    在学校的安保、设备巡检、IT机房设备维护以及酒店民宿客房服务等方面,由于管理跟不上,巡查人员容易出现态度松散的问题。这会导致漏检和错巡等“走流程式”巡查现象的出现。管理层对于巡查情况的了解也不够全面,等到出现问题时,往往已经演变成了大问题。 为了

    2024年02月09日
    浏览(41)
  • 工单管理系统哪家好?如何让学校后勤报修更方便?

    随着互联网的高速发展,学校宿舍管理也必须随之向数字化方向迈进。越来越多的企业利用云计算服务的优势,使后勤维护整个流程实现数字化、自动化运行以及资源共享。这些技术创新的运用,大大提高了学校宿舍的后勤维修管理水平,同时,学校宿舍报修系统以其便利、

    2024年02月13日
    浏览(42)
  • 设备工单管理系统如何实现工单流程自动化?

    设备工单管理系统属于工单系统的一种,基于其丰富的功能,它可以同时处理不同的多组流程,旨在有效处理发起人提交的事情,指派相应人员完成服务请求和记录全流程。该系统主要面向后勤管理、设备维护、物业管理、酒店民宿等服务行业设备工单管理系统可以帮助企业

    2024年02月13日
    浏览(39)
  • 【开源】基于JAVA+Vue+SpringBoot的大病保险管理系统

    基于Vue+SpringBoot+MySQL的城乡居民大病保险管理系统,包含患者档案、医保充值、保险档案、手术档案、看病登记、保险审核模块,包含系统自带的用户管理、部门管理、角色管理、菜单管理、日志管理、数据字典管理、文件管理、图表展示等基础模块,大病保险管理系统基于

    2024年01月23日
    浏览(54)
  • 高效的工单管理系统具备哪些特点?“的修”工单系统对民宿运营管理有什么好处?

    随着企业不断发展和业务扩展,工单管理已成为企业运营的必要组成部分。一个有效且高效的工单管理系统对企业的运营至关重要。为了实现这一目标,企业需要选择适合自身需求的工单管理解决方案,并建立科学的工单管理流程。 高效的工单管理系统具备以下特点: 高自

    2024年02月08日
    浏览(52)
  • java版工程管理系统Spring Cloud+Spring Boot+Mybatis实现工程管理系统源码

     工程项目管理软件(工程项目管理系统)对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营,全过程、全方位的对项目进行综合管理    工程项目各模块及其功能点清单 一、系统管理     1、数据字典:实现对数据字典

    2024年02月07日
    浏览(47)
  • vue-springboot微信小程序房地产房屋销售预约看房管理系统

    相比于以前的传统手工管理方式,智能化的管理方式可以大幅降低房地产公司的运营人员成本,实现了房地产销售的标准化、制度化、程序化的管理,有效地防止了房地产销售的随意管理,提高了信息的处理速度和精确度,能够及时、准确地查询和修正房地产信息、房源信息

    2024年02月04日
    浏览(41)
  • 基于python图书馆管理系统和读者系统(附完整代码以及打包好的exe文件)

    摘要:         本文基于python的图书馆管理系统和读者系统,实现了登录、注册、忘记密码、书籍查询、借阅、归还、修改等功能,通过csv文件将数据存储在本地。注册时采用了邮箱验证码,模拟了现实场景。( 全部源代码地址见文末 )如果有其他奇思妙想或者bug欢迎提

    2024年02月07日
    浏览(50)
  • Unity刚体之碰撞接触

    1.想要让程序判断两个物体又接触,则两个物体都必须要有Collider,并且运动的物体必须要有刚体,才会发生碰撞。如果运动的物体没有刚体,也视为没有碰撞。 2 .Collision碰撞 : 会发生物理碰撞, 双方都有碰撞体(Collider ), 至少有一个物体有rigidbody ,会触发OnCollision事件。

    2024年02月16日
    浏览(34)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包