Unity 刚体的 默认力、瞬时力 区别

张开发
2026/5/2 1:16:26 15 分钟阅读

分享文章

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

更多文章