Unity 刚体的 默认力、瞬时力 区别
想象你在推一辆超市购物车:
ForceMode.Force(默认力)= 你持续地推
你的动作:你把手按在车上,一直不停地推。
效果:车会慢慢加速,你推得越久,车跑得越快。
关键:这个力是持续的,只要你手不离开,力就一直在。
在代码里:你需要在每一帧(或者更准确地说,在
FixedUpdate里)都调用AddForce。如果你只调用一次,物理引擎会理解为:“哦,你只在这一瞬间推了一下,然后就松手了。”
ForceMode.Impulse(瞬时力)= 你猛地踢一脚
你的动作:你猛地踢了车一脚,脚立刻离开。
效果:车会瞬间获得一个速度,然后自己滑出去。踢的力气越大,初始速度越快。
关键:这个力是瞬间的一次性爆发。脚离开后,力就没了,车靠惯性运动。
在代码里:你只需要在踢的那一帧调用一次
AddForce,物理引擎就知道:“这一下是爆发,后面没有了。”
使用AddForce方法,传入同样的力值,使用Force 、Impulse 有本质区别:
一个直观的实验:
假设质量 = 1,Time.fixedDeltaTime = 0.02(默认值):
// 两行代码,数值都是 10 rb.AddForce(10f, ForceMode.Force); // 持续力 rb.AddForce(10f, ForceMode.Impulse); // 瞬时力结果完全不同:
| 模式 | 实际效果 | 产生的速度 |
|---|---|---|
| Force | 在一帧内(0.02秒)施加 10N 的力 | 10 × 0.02 ÷ 1 =0.2 米/秒 |
| Impulse | 在一瞬间施加 10 N·s 的冲量 | 10 ÷ 1 =10 米/秒 |
同样的数值 10,Impulse 产生的速度是 Force 的 50 倍!
为什么会有这种差异?
因为它们的物理含义不同:
| ForceMode.Force | ForceMode.Impulse | |
|---|---|---|
| 单位 | 牛顿 (N) | 牛顿·秒 (N·s) |
| 含义 | "每秒钟施加多少力" | "一次性给多少冲量" |
| 计算公式 | 速度变化 = 力 × 时间 ÷ 质量 | 速度变化 = 冲量 ÷ 质量 |
关键点:Force多乘了一个Time.fixedDeltaTime(约 0.02 秒),所以效果被严重缩小了。
提问1: 我在按键时,实时地调用 rb.AddForce(...,ForceMode.Force),对象为什么会不停加速?
用推车的例子来理解
想象你每秒钟推车 60 次(60帧):
第1次推:车从静止开始慢慢动
第2次推:车还没停下来,你又补了一推
第3、4、5次...:你不停地推,车就会越来越快
物理上完全正确:你一直给力,物体就一直加速。
为什么现实中车不会无限加速?
现实中有阻力:
空气阻力
轮胎与地面的摩擦力
这些阻力会抵消你的推力。当推力 = 阻力时,速度就不再增加了(达到终端速度)。
印次你需要在刚体组件里设置Drag(阻力)(默认为0):
Drag = 0:无限加速(太空)
Drag = 1~5:会达到一个最大速度(汽车、飞机)
补充: 只要阻力(Drag)大于 0,遇到持续施加一个恒定的力,最终速度会稳定在一个固定值,不再增加。
提问2: 是不是可以只使用ForceMode.Force 传入一个很大的力,来替代ForceMode.Impulse呢?
不可以,它们各自有不可替代的用途。
想象这个场景
你想实现一个跳跳床:
角色踩上去的那一瞬间,被猛地弹起来
弹起的速度很快,但只发生在接触的那一帧
如果用 ForceMode.Force 会怎样?
// 错误:用 Force 模拟跳跃 void OnCollisionEnter(Collision collision) { rb.AddForce(Vector3.up * 1000f, ForceMode.Force); }问题:
| 问题 | 说明 |
|---|---|
| 依赖时间 | 效果取决于 (当别人修改了fixedDeltaTime时,你的力计算就会出错。) |
| 难以调参 | 你需要手动计算:目标冲量 ÷ Time.fixedDeltaTime = 应该填的数值。比如要 10 的冲量,Time.fixedDeltaTime=0.02,就要填 500 |
| 语义混乱 | 阅读代码的人会困惑:“这里是想持续推一秒钟?还是只是跳一下?” |
正确代码:使用 ForceMode.Impulse :
// 正确:用 Impulse 模拟跳跃 void OnCollisionEnter(Collision collision) { rb.AddForce(Vector3.up * 10f, ForceMode.Impulse); }优点:
与时间无关:无论物理帧率如何,跳跃高度始终一致
直观调参:填 10 就是“一次性给 10 的冲量”,不需要任何换算
语义清晰:看到
Impulse就知道“这是一次性爆发”
