Unity 物理系列二 AddForce velocity

Unity 物理系列二 AddForce velocity,第1张

https://docs.unity3d.com/cn/2019.4/ScriptReference/Rigidbody.AddForce.html

https://docs.unity3d.com/cn/2019.4/ScriptReference/ForceMode.html

Unity中关于作用力方式ForceMode的功能注解

功能注解:ForceMode为枚举类型,用来控制力的作用方式,有4个枚举成员,在以下举例中均设刚体质量为m=2.0f,力向量为f=(10.0f,0.0f,0.0f)。

默认方式,使用刚体的质量计算,以每帧间隔时间为单位计算动量。设FixedUpdate()的执行频率采用系统默认值(即0.02s),,则由动量定理f•t=m•v可得:10*0.02=2*v1,从而可得v1=0.1,即每帧刚体在X轴上值增加0.1米,从而可计算得刚体的每秒移动速度为v2=(1/0.02)*v1=5m/s。

在此种作用方式下会忽略刚体的实际质量而采用默认值1.0f,时间间隔以系统帧频间隔计算(默认值为0.02s),即f•t=1.0•v即可得v1= f•t=10*0.02=0.2,即刚体每帧增加0.2米,从而可得刚体的每秒移动速度为v2=(1/0.02)*v1=10m/s。

此种方式采用瞬间力作用方式,即把t的值默认为1,不再采用系统的帧频间隔,即f•1.0=m•v即可得v1=f/m=10.0/2.0=5.0,即刚体每帧增加5.0米,从而可得刚体每秒的速度为v2=(1/0.02)*5.0=250m/s。

此种作用方式下将忽略刚体的实际质量,采用默认质量1.0,同时也忽略系统的实际帧频间隔,采用默认间隔1.0,即f•1.0=1.0•v即可得v1=f=10.0,即刚体每帧沿X轴移动距离为10米,从而可得刚体每秒的速度为v2=(1/0.02)*v1=500m/s。

https://docs.unity.cn/cn/2019.4/ScriptReference/Rigidbody-velocity.html

刚体的速度矢量。它表示刚体位置的变化率。

在大多数情况下,不应该直接修改速度,因为这可能导致行为失真 - 改用 AddForce

请勿在每个物理步骤中设置对象的速度,这将导致不真实的物理模拟。 需要更改速度的一个典型用法是第一人称射击游戏中的跳跃动作设计,因为此时需要立即更改速度。

酷游戏的一些bug总结(滥用FixedUpdate的坑)

Unity3D中Rigidbody.velocity和Addforce的区别

假设我们想要做一个2D的跳跃游戏,在这个游戏里我希望我按下跳跃键的时候,游戏物体的跳跃高度是恒定的。

那么,如果此时我使用的是addForce显然不会满足我的效果,因为经过测试,每按一下跳跃键,它会被施加一个恒定的力,它跳跃的初始速度会越变越大,每次跳跃的高度和前一次相较变得越来越大(在连续跳跃的情况下),也就是可以理解成,我现在被施加了一个大小为50的力,在重力作用下我的力的效果在减小,在正向速度还没有完全消失的情况下,此时我又按了一下跳跃键,那么就会在这个力的基础上再施加一次大小为50的力,物体会越跳越快,越跳越高。

而此时如果我们使用的是velocity方法 改变它的初始速度到我们希望的值和方向 ,那么当我们按下跳跃键的时候,无论此时物体减速到何种情况,也最多只会提升到我们规定的速度以及朝向我们规定的方向。初始速度不变的情况下,跳跃高度也是恒定的。

解决:

AddForce之前应该清一下速率,因为是射线检测是否碰到地面,而跳跃后不会立刻离地。如果不清,后面几帧会累加AddForce。 清除速率保证离地的一瞬间肯定是正常Force,而非累加Force。

我们常在Unity开发中直接使用Rigidbody.velocity属性来获取刚体的当前速度,这在大多数情况下是没有问题的。但在某些情况下这么做就可能得不到我们想要的结果。比如通过transform.Translate(), transform.RotateAround(), rigidbody.MovePosition(), Vector3.MoveTowards() 等方法 “强制” 改变刚体的运动状态时,此时物体速度的改变并不会引起Rigidbody.velocity的改变。

而当我们把所有球的刚体组件中的Is Kinematic属性勾选上后,我们再来看看运行结果:

OMG!【仅移动】小球的Rigidbody.velocity居然又和真实速率一致了!

我并不了解Rigidbody.velocity这个属性在内部是如何被定义的,官方文档没有相关的说明,网上也没有找到相关的资料,我个人只能根据这些现象做如下的一些推测。

当刚体的Is Kinematic没有被勾选时,刚体的运动就被Unity的物理引擎所掌控,物体的运动和状态都会遵循真实世界的物理定律。我们知道,在牛顿力学中,要改变一个物体的运动状态必须要对其施加力,Unity也为我们提供了AddForce()方法。然而像MovePosition()这样的方法似乎可以让物体的运动随心所欲,能够以任意速度到达任意位置,可以让物体瞬间加到一个非常大的速度。显而易见,这种对运动状态的 “ 强制 ” 改变必定不能通过加力的方式实现,这就已经脱离了真实世界的物理定律了。 被物理引擎控制的物体擅自进行了不按套路的 *** 作,Rigidbody.velocity就不会记录这种 “非法” *** 作带来的速度改变,或者将这种非法 *** 作对velocity的改变视为0。

反之,当刚体的Is Kinematic被勾选时,刚体的运动就脱离了Unity的物理引擎控制。风水轮流转,天道好轮回,这种情况下MovePosition()成了合法 *** 作,AddForce()成了非法 *** 作了。想要报仇雪恨的MovePosition()积攒了多年的怨气,对非法 *** 作的限制变得更为严格,之前的情况还允许非法 *** 作对物体运动状态的改变,这次已经完全屏蔽了AddForce()的作用。 从上一张截图就可看出,这次即便加力物体也始终保持静止。此时此刻MovePosition()终于作为合法 *** 作被Rigidbody.velocity认可,使其能够反映物体真实速率。

总结

通过以上案例,我的想法就是最好不要对未勾选Is Kinematic的刚体使用 transform.Translate(), transform.RotateAround(),rigidbody.MovePosition(),Vector3.MoveTowards() 等等这些方法,毕竟这些非常规 *** 作必定会对物理模拟的真实性产生影响。如果你不得不使用时,也请注意Rigidbody.velocity并不是物体在场景和游戏视图中的真实速度,不要滥用这些方法和这个属性而不小心掉入它的 “ 陷阱 ”。

https://docs.unity.cn/cn/2019.4/Manual/class-ConstantForce.html

恒定力 (Constant Force) 可用于快速向 刚体 添加恒定力。如果不希望某些一次性对象以较大的速度开始而是逐渐加速(比如火箭),则很适合使用恒定力。

要制作一个向前加速的火箭,请将 Relative Force 设定为沿正 z 轴。然后,使用刚体的 Drag 属性使其不超过某个最大速度(阻力越高,最大速度越低)。在刚体中,还要确保关闭重力,以便火箭始终保持在其路径上。

1.首先,打开自己的unity3d场景,如下所示。

2.然后创建一个基本的模型对象在该方案中,如下所示。

3.向对象添加Rigidbody属性,如下图。

4.创建两个脚本,Add_script和力量,如下所示。

5.打开Add_script,通过内表面的AddComponent将Forcescript添加到objectCapsule中,通过Destroy删除script组件,分别设置space和delete按钮。

UnityEngineInternal。APIUpdaterRuntimeServices。AddComponent (GameObject。查找(“胶囊”)、“添加力”、“力”)销毁(GetComponent <Force >())。

6.将Add_script脚本添加到对象中,如下图。

7.按空格键将force脚本添加到对象山中。

8.现在,您可以添加一个力对象移动的对象,所以脚本,如下所示。

9.然后按下删除键,脚本对象将被删除,让您可以灵活地将删除脚本添加到对象,如下所示。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/bake/11189924.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-14
下一篇 2023-05-14

发表评论

登录后才能评论

评论列表(0条)

保存