Eri*_*ast 3 unity-game-engine game-physics
关于何时应该或不应该将数量乘以 ,似乎有很多令人困惑/矛盾的建议Time.deltaTime
。所以我想知道,因为它与 Unity 物理系统有关,你应该在Time.deltaTime
什么时候乘以?
我知道 Time.deltaTime 用于使某些动作与帧速率无关,但在某些情况下,不清楚动作是否与帧速率无关。例如:
rigidbody.velocity += acceleration*Time.deltaTime;
在 FixedUpdate 中做。由于 FixedUpdate 以恒定时间步长运行,这是否使乘法变得Time.deltaTime
不必要?rigidbody.AddForce(force*Time.deltaTime, forceMode);
。各种ForceMode
s 对此有何影响?我已经看到了针对个别情况的解决方案,但如果有一种简单的直觉可以解决所有这些情况,那就太好了。
Eri*_*ast 11
乘以Time.deltaTime
用于使瞬时操作以连续(或“平滑”)方式进行。
瞬时操作会导致某个数量“跳”到不同的值。以下操作是即时的:
Rigidbody.[position|velocity|rotation|angularVelocity] += x;
Rigidbody2D.[position|velocity|rotation|angularVelocity] += x;
Rigidbody.Add[Force|Torque](x, ForceMode.[Impulse|VelocityChange]);
Rigidbody2D.Add[Force|Torque](x, ForceMode2D.Impulse);
以上所有操作都会导致一个数量立即跳过x
,而与帧的长度无关。
相比之下,以下操作是连续的:
Rigidbody.Add[Force|Torque](x, ForceMode.[Force|Acceleration]);
Rigidbody2D.Add[Force|Torque](x, ForceMode.Force);
Rigidbody.velocity = x;
(从连续的角度来看Rigidbody.position
。即设置速度不会使Rigidbody.position
突然跳到新值)以上所有操作都应用于整个框架的过程(至少在概念上会发生这种情况;物理系统在内部所做的事情超出了本答案的范围)。为了说明这一点,Rigidbody.AddForce(1, ForceMode.Force)
将在整个框架内对对象施加 1 牛顿的力;不会出现位置或速度的突然跳跃。
Time.deltaTime
什么时候乘以?如果您使用的是连续运算,则几乎绝对不应该乘以Time.deltaTime
。但是,如果您使用的是瞬时操作,则答案取决于该操作是否以连续方式使用。
void Explode() {
rigidbody.velocity += explosionAcceleration;
}
Run Code Online (Sandbox Code Playgroud)
在这里你不应该乘以Time.deltaTime
因为只Explode()
被调用一次。它并不意味着应用于一系列帧。
void Update() {
rigidbody.position += velocity * Time.deltaTime;
}
Run Code Online (Sandbox Code Playgroud)
在这里,您确实必须乘以,Time.deltaTime
因为对象应该随着时间的推移连续移动,并且您还使用了瞬时操作。请注意,这可以用连续操作代替,并且不需要乘以Time.deltaTime
:
void Update() {
rigidbody.velocity = velocity;
}
Run Code Online (Sandbox Code Playgroud)
尽管这并不完全等同于原始值,因为它忽略了rigidbody.velocity
.
void Update() {
rigidbody.AddForce(acceleration*Time.deltaTime, ForceMode.VelocityChange);
}
Run Code Online (Sandbox Code Playgroud)
在这里,您应该乘以 ,Time.deltaTime
因为您希望速度以一致的速率逐帧增加。请注意,这完全等同于:
void Update() {
rigidbody.AddForce(acceleration, ForceMode.Acceleration);
}
Run Code Online (Sandbox Code Playgroud)
此代码在整个帧的过程中应用加速度。这段代码(在我看来)也更清晰、更容易理解。
FixedUpdate
?入住FixedUpdate
不会影响上述任何建议。是的,理论上你可以从不乘以逃脱,Time.deltaTime
因为帧之间的时间总是相同的。但是你所有的单位都必须依赖于固定的帧速率。因此,举例来说,如果你想的速率移动1 m/s
与60
帧每秒,你就必须添加1/60=.01666
到每一帧的位置。然后想象一下如果你改变你的固定时间步长会发生什么。您将不得不更改一堆常量以适应。
执行代码FixedUpdate
不会突然使代码帧率独立。您仍然必须采取与 中相同的预防措施Update
。
作为旁注,您不需要Time.deltaTime
用Time.fixedDeltaTime
inside替换,FixedUpdate
因为 Unity 已经进行了此替换。
仅Time.deltaTime
当您希望瞬时操作在一系列帧上平滑运行时才乘以。
很多时候,你可以Time.deltaTime
通过使用连续操作来避免使用,这通常更直观(参见示例 2 和 3)。但这当然取决于上下文。
归档时间: |
|
查看次数: |
2313 次 |
最近记录: |