第二十五章 Unity 刚体Rigidbody
在物理学中,静止和匀速直线运动是物体的平衡状态,如果给该物体施加某一个力的话,物体的平衡状态就会改变,当然这个真理的前提是理想状态。我们知道在现实世界中,由于重力和摩擦力的存在,任何一个物体都不可能永无止境的运动下去。因此,要想让物体保持运动状态,我们就必须持续的给物体施加一个力。在Unity中就模拟了这种效果,它是通过一个叫做“Rigidbody刚体”的组件实现的。接下来,我们就来创建一个“PhysicsDemo”3D工程来介绍Rigidbody刚体组件。
首先,我们创建了一个平面,然后在平面的上方创建了一个球体。
接下来,我们就给球体添加刚体Rigidbody组件。添加操作非常简单,可以在球体的Inspector检视视图下面点击“Add Component”。
我们在搜索框中输入“ri”,就会在下拉框中就能看到“Rigidbody”组件,注意不要选择“Rigidbody 2D”,这个虽然也是刚体,但是它是用于2D游戏对象的。我们是这里要选择的是3D的“Rigidbody”组件。
在“Rigidbody”刚体组件下有很多参数,我们暂时先不介绍,直接运行工程来查看添加刚体组件后的球体会有什么效果。如下所示:
运行后,我们发现球体直接落到了平面上面。这是因为,给球体添加刚体组件后,球体就会受到“重力”的作用,沿着Y轴方向向下掉落,直到碰到平面而停止。这个“重力”就是“Rigidbody”刚体组件产生的效果。刚体会接管附加到的游戏对象的运动,如果我们施加一个力来推动游戏对象的话,Unity会自动计算该游戏对象的运行效果。如何施加一个力呢?我们点击菜单栏“Component”->“Physics”->“Constant Force” 恒定力组件。
我们在“Constant Force” 恒定力组件的Force参数的X值修改为2,也就是在X轴方向上施加数值为2的一个力来作用于当前球体。我们运行工程,查看效果。
我们发现球体受到重力作用掉落后,还同时受到X轴方向的力而向右继续运动。但是,有时候我们不希望游戏物体以这样的方式运行,因此我们需要游戏对象的运动摆脱Unity物理引擎的控制。刚体组件有一个名为 Is Kinematic 的属性,该属性可以让刚体摆脱物理引擎的控制,并允许通过脚本以运动学方式来移动刚体。接下来,我就来讲解刚体的一些参数。
Mass 游戏对象的质量(默认单位为千克)。
Drag 游戏对象移动时受到阻力的大小,0 表示没有阻力。
Angular Drag 游戏对象旋转时受到阻力的大小,0 表示没有角阻力。
Use Gravity 如果启用此属性,则对象将受重力影响。默认是启用状态。
Is Kinematic 如果启用此选项,则对象将不会被物理引擎驱动,上文中已经提到。
Interpolate 仅当在刚体运动中看到抖动时才尝试使用提供的选项之一。
- None 不应用插值。
- Interpolate 根据前一帧的变换来平滑变换。
- Extrapolate 根据下一帧的估计变换来平滑变换。
Collision Detection 用于防止快速移动的对象穿过其他对象而不检测碰撞。
Discrete为默认值,表示对场景中的所有其他碰撞体使用离散碰撞检测。
Constraints 对刚体运动的限制,可以限制在X/Y/Z某一轴向上移动或旋转。我们展开下面有两个子项,分别是冻结位置和冻结旋转,每一个冻结子选项都分为X,Y,Z三个轴向的冻结。如果当刚体操作游戏物体运动的时候,不会在这些轴向上产生移动或旋转。
在上面的案例中,我们使用“Constant Force” 恒定力组件给球体施加一个力,让其产生运动。如何使用脚本来使用刚体控制物体运动,或者说如何使用脚本给游戏对象施加一个力呢?首先,我们先取消“Constant Force” 恒定力组件,如下所示
我们只需要取消“Constant Force”组件前面的勾选项即可。接下来,我们创建一个脚本SphereScript.cs,然后附加到球体上面,代码如下所示
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class SphereScript : MonoBehaviour
{// 刚体组件private Rigidbody rbody;// Start is called before the first frame updatevoid Start(){rbody = GetComponent<Rigidbody>();}// Update is called once per framevoid Update(){if (Input.GetKeyDown(KeyCode.A)){rbody.AddForce(Vector3.right * 100);}}
}
上述代码就是,当我们按下键盘A键的时候,使用刚体的AddForce方法给球体施加一个Vector3.right方向,大小为100。这里需要注意的是,AddForce施加的力在 FixedUpdate 中计算,而FixedUpdate时间间隔一般是0.02秒。代码完成之后,我们还需要做一个非常关键的设置,就是取消Use Gravity,如下所示
这样,球体就不再受重力影响掉落到平面上面了。我们可以Play运行一下。
我们发现,球体不再掉落下来,并且当我们按下A键的时候,球体向右开始移动。我们知道,移动的物体,最重要的是速度。当我们给物体施加一个力的时候,这个速度与力的关系是如何呢?我们修改一下代码,打印刚体的速度velocit 值。
// Update is called once per framevoid Update(){if (Input.GetKeyDown(KeyCode.A)){rbody.AddForce(Vector3.right * 100);}Debug.Log(rbody.velocity);}
我们增加一个日志,输出游戏物体的速度。我们重新Play工程
我们发现,当我们施加一个力的时候,球体开始运动,X轴向速度是2.0。这个数值是怎么计算得来的呢?首先了解一下动量定理:物体在一段时间Δt内的动量变化量等于它在这个过程中所受力的冲量,也就是力与力的作用时间的乘积,数学表达式为:FΔt = mΔv 。其中F就是这个力的大小,Δt就是这段时间,m就是物体的质量,Δv表示这段时间的平均速度。我们球体对象的质量mass为1(在Rigidbody组件中设置的),然后给它一个X轴正方向大小为100的力。AddForce方法还有第二个参数ForceMode,代表施加力的类型。ForceMode为枚举类型,有4个枚举成员:ForceMode.Force,ForceMode.Acceleration,ForceMode.Impulse,ForceMode.VelocityChange。
他们代表的含义如下所示:
ForceMode.Force 默认方式,使用刚体的质量计算,以每帧间隔时间为单位计算动量。我们上面已经说了FixedUpdate按0.02s秒计算,则由动量定理公式FΔt = mΔv可得, 速度v = FΔt / m = 100 * 0.02 / 1 = 2.0米/秒。也就是说,刚体1秒移动2米的距离。
ForceMode.Acceleration表示忽略游戏对象的质量(相当于质量固定为1)。
ForceMode.Impulse 表示采用瞬间力作用方式,即把Δt的值默认为1,速度会变快。
ForceMode.VelocityChange 表示忽略质量和时间(两者均固定为1),速度就更加快了。
最后,我们要讲解一下刚体的阻力Drag值。在现实世界中,物体移动一定会受到阻力的影响,其速度会慢慢减少,最终停止运动。在Unity中,为了能够让物体运动一段距离后停止,我们可以给刚体组件增加阻力Drag值。接下来,我们给刚体增加1的阻力值。
然后,我们在重新Play工程,查看日志中速度的变化。
我们发现,刚体的速度从2.0开始依次减少0.1的速度。阻力与速度之间的公式是什么呢?网上查询了PhysX得知:velocity = velocity * ( 1 - deltaTime * drag); 也就是说,速度会随着每帧的执行,越来越小,直到为零。假如阻力为1的话,游戏对象会在运动1秒后速度减小到零(静止不动)。也就是说,不管施加的力有多大,当阻力为1的时候,游戏对象都会在1秒后静止。但是,从我们实际的运行情况来看,好像也没有那么的准确。而且,如果发生碰撞的话(球体在平面上),速度也会不断减少。
我们总结一下:刚体可以接受力和扭矩,力可以让刚体对象移动,扭矩可以让刚体对象旋转,向刚体施加力/扭矩实际上会改变对象的变换组件的位置和旋转。我们可以通过刚体的AddForce或AddTorque方法来给游戏对象添加力或者扭矩。但是,在实际开发中,我们可能取消Use Gravity重力影响,勾选Is Kinematic属性,使用代码控制游戏对象平移或旋转变换。两者各有各的优势,刚体可以模拟现实世界的运动效果,而代码控制更加灵活。并且,刚体组件一般都是搭配碰撞体组件一起使用的。另外,当处于休眠模式的刚体收到外界的影响时候,刚体会被唤醒,继续参与物理运算。如果希望通过脚本来控制刚体的休眠状态,可以调用刚体的Sleep和WakeUp方法让刚体进入休眠或者从休眠中唤醒。
第二十五章 Unity 刚体Rigidbody相关推荐
- 第二十五章补充内容 3 assert()宏
//第二十五章补充内容 3 assert()宏 //有的编译器还提供了assert()宏,这个宏在许多书中被翻译为断言,它的作用是当assert()的参数为真时,返回真,假如参数值为假,那么它将执行某 ...
- 25 linux ndk 头文件_正点原子Linux第二十五章RTC实时时钟实验
1)资料下载:点击资料即可下载 2)对正点原子Linux感兴趣的同学可以加群讨论:935446741 3)关注正点原子公众号,获取最新资料更新 第二十五章RTC实时时钟实验 实时时钟是很常用的一个外设 ...
- 鸟哥的Linux私房菜(基础篇)- 第二十五章、 Linux 备份策略
第二十五章. Linux备份策略 最近升级日期:2009/09/18 万一不幸你的 Linux 被黑客入侵了.或是你的 Linux 系统由於硬件关系 (不论是天灾还是人祸) 而挂掉了!这个时候,请问如 ...
- 第二十五章补充内容 5 不能为0的变量
// 第二十五章补充内容 5 不能为0的变量 /*#define DEBUG #include <iostream> #include <string> using names ...
- 第二十五章:重新吃上饭的李恪
第二十五章:重新吃上饭的李恪 可能李丽质永远都不会忘记了自己饿肚子饿了很久以来的第一顿饭吧. 吃的非常的香,吃完这顿饭以后,李丽质开始也参与到了洗皮衣的过程中,不过由于他个子比较小,所以只能做一些简单 ...
- 现实迷途 第二十五章 重见故人
第二十五章 重见故人 注:原创作品,请尊重原作者,未经同意,请勿转载,否则追究责任. 两天后,狗子又变得生龙活虎了,他决定要和江北不醉无归. "你想斋喝,还是荤喝?"电话中狗子问江 ...
- 游戏设计的艺术:一本透镜的书——第二十五章 好的游戏是通过游戏测试做出来的
这是一本游戏设计方面的好书 转自天之虹的博客:http://blog.sina.com.cn/jackiechueng 感谢天之虹的无私奉献 Word版可到本人的资源中下载 第二十五章好的游戏是通过游 ...
- 系统集成项目管理工程师(软考中级)—— 第二十五章 法律法规(补充) 笔记分享
前言 最近在复习软考高级,比较少更新.. 现在分享一些笔记给大家,希望能够帮助大家并顺利通过软考. 幕布地址:(补充)第二十五章 法律法规 - 幕布 概述 法规法规部分涉及招投标法.招投标法实施条例. ...
- 【正点原子STM32连载】 第二十五章 TFTLCD(MCU屏)实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1
1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...
最新文章
- 三星笔记本桌面计算机图标消失,重启电脑我的电脑图标不见了怎么处理
- ELK/EFK — 安装部署(主机安装)
- 再见,Navicat!这个Pycharm的兄弟真香!
- 在macOS X中gdb的codesigned问题解决
- Java 证书pem转KeyStore、jks文件
- python模板引擎传迭代器_python之路 模块,序列化,迭代器,生成器
- android本地图片,Android中ImageView实现选择本地图片并显示功能
- Selenium TestNG Java环境搭建过程中所遇问题汇总
- Unity zSpace 开发
- 通达信最新 行情服务器,通达信行情服务器数据
- PS文字的投影怎么打?
- 全国计算机二级重难点,计算机二级office重难点.doc
- AI的10个开源工具/框架
- 【腾讯TMQ】我们在外包资源池化管理走过的弯路
- 群晖emby服务端下载(弃坑,官网已经能顺畅访问)
- Win10 不支持 Miracast 无法投影解决方案
- Linux离线安装Python第三方库Requests
- 服务器连接数据库mysql
- CC2640R2F BLE5.0 CC2640R2F UART驱动
- 全国电费充值优惠接口源码