【Untiy学习笔记】Rigidbody组件及其常用函数 | 您所在的位置:网站首页 › transform组件的作用和属性 › 【Untiy学习笔记】Rigidbody组件及其常用函数 |
前言
提示:声明:此篇文章是个人学习笔记,并非教程,所以内容可能不够严谨。可作参考,但不保证绝对正确。如果你发现我的文章有什么错误,非常欢迎指正,谢谢哦。 本文大部分内容来自官方文档!!! 官方手册:Rigidbody 官方API:Rigidbody Api 一、 Rigidbody组件简介如果希望某个游戏物体能够受到物理系统中力的影响,就要添加此组件 二、Rigibody组件属性(百度百科)离散点的碰撞检测是指定某一时刻T的两个静态碰撞体,看它们之间是否交迭,如果没有交迭则返回它们最近点的距离,如果交迭则返回交迭深度,交迭方向等。连续碰撞检测则是分别指定在T1、T2两个时刻两个碰撞体的位置,看它们在由T1运动到T2时刻的过程中是否发生碰撞,如果碰撞则返回第一碰撞点的位置和法线。连续碰撞检测是最为自然的碰撞检测,可以大大方便碰撞响应逻辑的编写,可以很容易避免物体发生交迭或者穿越。离散点的碰撞检测则没有那么友好,当检测到碰撞时两个物体已经发生了交迭,如果其中有三角形网格对象那么已经有许多三角形发生了交迭,如何将两个交迭的对象分开并按合理的方式运动是一个挑战。虽然连续碰撞检测是最自然的方式,但它的实现非常复杂,运算开销也很大 我的理解:离散碰撞会在每一帧检测两个物体是否有重叠部分,如果没有重叠部分就表示两个物体没有碰撞。在这种情况下,如果物体速度过快,可能第一帧A在B前面,第二帧A就在B后面了,因为这两帧二者都没有重叠,就会被当作没有发生碰撞处理了。 添加Rigidbody后,移动或者旋转物体最好就不要用Transform了,容易出现问题。应该直接调用Rigidbody组件提供的函数或属性。推荐在FixedUpdate函数中调用这些施加力的函数, 而不要Update函数中调用。物理的更新和Update的帧频率不是匹配的,但是FixedUpdate函数是在每次物理更新之前调用,就正好把更新的数据传入物理系统。 函数名称功能函数声明参数说明AddExplosionForce给Rigidbody施加了一个力模拟爆炸效果。力会施加到物体距离爆炸中心最近的表面上的点。public void AddExplosionForce(float explosionForce, Vector3 explosionPosition, float explosionRadius, float upwardsModifier = 0.0f, ForceMode mode = ForceMode.Force));explosionForce:爆炸的力度,可随距离变化。 explosionPosition:爆炸中心位置explosionRadius:爆炸半径。如果设为0,则表示不管距离爆炸中心多远都承受全部的力。upwardsModifier:可将施加力的位置沿Y轴移动-upwardModifier,但是力的大小不变,可用于营造物体被炸到空中的效果。mode:施加力的方式,参见下方“参数ForceMode”AddForce给Rigidbody添加一个力public void AddForce(Vector3 force, ForceMode mode = ForceMode.Force);Force:力的方向和大小。mode:施加力的方式,参见下方“参数ForceMode”AddForceAtPosition在指定点施加力.如果想要真实的效果,力的施加位置应在物体表面附近public void AddForceAtPosition(Vector3 force, Vector3 position, ForceMode mode = ForceMode.Force);force:力的方向和大小 。position:施加力的位置。mode:施加力的方式,参见下方“参数ForceMode”AddRelativeForce施加一个相对其自身坐标系的力public void AddRelativeForce(Vector3 force, ForceMode mode = ForceMode.Force);force:力的方向和大小。mode:施加力的方式,参见下方“参数ForceMode”AddTorque给Rigidbody添加一个扭矩/转矩,让物体旋转。会发现物体的旋转速度达到一定就不能再增加了,可以通过修改maxAngularVelocity解决。public void AddTorque(Vector3 torque, ForceMode mode = ForceMode.Force);torque:扭矩/转矩方向和大小。mode:施加力的方式,参见下方“参数ForceMode”AddRelativeTorque施加一个相对其自身坐标系的扭矩。public void AddRelativeTorque(Vector3 torque, ForceMode mode = ForceMode.Force);torque:扭矩/转矩方向和大小。mode:施加力的方式,参见下方“参数ForceMode”MovePosition让Rigidbody移动到指定位置。会根据Rigidbody组件的Interpolate属性进行计算 。如果想要传送Rigidbody,直接设置Rigidbody.position的值即可public void MovePosition(Vector3 position);position:世界坐标系位置MoveRotation将Rigidbody旋转到指定角度(四元数)。会根据Rigidbody组件的Interpolate属性进行计算public void MoveRotation(Quaternion rot);rot:想要rigidbody达到的旋转角度 参数ForceMode我们都知道,力作用在物体上会增加物体的移动速度(不考虑摩擦),而随着力作用的时间越长增加的速度就越大。因此我们使用Rigidbody的函数施加力的时候,也要考虑力作用的时间长度,其中ForceMode参数就是用来设置作用时间长度的。 ForceMode意为施加力的模式,它是个枚举类型,在我们使用上面的函数给Rigidbody施加力的时候,可以传入具体值来指定施加力的方式。本质上就是用来指定力的作用时间长度的,函数会根据指定的ForceMode的值,计算施加力后Rigidbody的速度值。 下面例子均为假设物体初速度2,质量为5,而施加力为10(水平X轴方向)的情况 值含义Force表示力作用到物体0.02s(一个固定帧的时间长度/FixedUpdate函数的执行间隔,可修改)。物体的速度直接变为该力作用到物体0.02s后的速度。 速度 = v0+at = v0 + f/mt = 2+10/50.02=2.04Impulse表示力作用到物体1s,物体的速度直接变为该力作用到物体1s后的速度。 速度 = v0+at = v0 + f/mt = 2+10/51 = 4Acceleration和Force一样,不过会用1代替物体的实际质量。速度 = v0+at = v0 + f/mt = 2+10/10.02=2.2VelocityChange和Impulse一样,不过会用1代替物体的实际质量。速度 = v0+at = v0 + f/mt = 2+10/11=12 四、补充: Transform和RigidbodyTransform组件和Rigidbody组件都可以用来移动和旋转物体,在Transform上修改物体位置或者旋转,是直接修改物体坐标来移动物体不涉及物理系统。而使用Rigidbody组件移动和旋转物体是会参与物理系统计算的。通常情况下,同一个物体只会使用Transform或Rigidbody中的一个来对物体移动或旋转,如果同时使用两个可能会出现问题。 关于父子关系1.Rigidbody使用的collider是{本物体的Collider以及所有没有Rigidbody的子物体的Collider组成的整体}。换个说法,某个物体有collider但是没用rigidbody,那么它的collider会作为有rigidbody的父物体的collider。 2.有Rigidbody组件的物体的物理碰撞效果是单独的,会与父物体分隔开。 例如:有三个球体分别是(1) Red、(2) Green、(3) Blue。其中(1) Red和(2) Green有Rigidbody,而(3) Blue没有。它们的父子关系如下 默认情况下,Unity的1个单位表示1米。如果你发现物体的物理效果不合意,要考虑模型大小是否符合现实。大楼倒塌的方式和玩具积木是不同的。所以最好在建模时按照真实的尺寸。如果导入的模型尺寸不合适,你又不方便去调整模型了,可以点击导入的模型,在Import Setting中修改缩放比例。 另外要注意,如果你在游戏中实例化不同尺寸的同一物体,你可以选择修改Transform上的Scale缩放物体,但是这种做法会让物理系统多消耗一丢丢资源,无伤大雅,但是更好的方法是上面提到的两种。 提示1.两个Rigidbody的相对Mass(质量)会决定二者碰撞时的效果。 2.想要一个物体下落比另一个慢,就去调整Drag(空气阻力)值。调整质量是毛有用滴。 3.一个低的Drag(空气阻力)值会让物体看起来更重,通常Drag的值为0.01(金属块)到10(羽毛)。 4.如果你想要使用Transform来控制物体移动但是又想保留物理效果,就添加Rigidbody组件然后勾选Is Kinematic。 5.如果你使用Transform移动某个物体,又希望能接收到碰撞或触发器的回调,那只能添加一个Rigidbody组件洛。 6.如果你想让一个物体停止旋转,仅仅将Rigidbody的Angular Drag 属性设为无限是没用滴。 本文大部分内容来自官方文档!!! |
CopyRight 2018-2019 实验室设备网 版权所有 |