Unity中Update方法和FixedUpdate之间的区别?


14

我开始学习Unity3d,而我得到的困惑之一是Update()和之间的区别FixedUpdate()

我在那儿遵循Lynda Unity 2D游戏开发教程,讲师使用Update方法,播放器具有RigidBody2D组件和Box collider,他使用该Update方法来翻译播放器,但是当我在Update播放器中执行相同操作时,它不会移动,但是当我执行时在中FixedUpdate,一切正常。他正在从Unity 4.3提供教程,而我正在Unity 4.6中学习课程。

我应该在哪里使用UpdateFixedUpdate

Answers:


14

我本来打算将其写为评论,但最终却花了很长的时间,因此我将其变成了答案。

当前的答案大部分是正确的,但是提到的一些事情是误导/错误的。

一般而言,大多数与游戏相关的任务都会进入Update

例如,您不想轮询输入FixedUpdate(不是因为性能,而是因为调用根本无法正常工作)。AI落在同一条船上。

不断更新的物理特性是唯一FixedUpdate应用于游戏性的任务。对,甚至属于之类的东西进行非连续/一次调用。我提到的内容似乎与文档可能暗示的内容相反,但是关键是Continuous VS Non-continuous。Physics.RaycastRigidbody.AddForceUpdateRigidbody.AddForce

只有连续物理学属于的一个巨大原因是物理学FixedUpdate的本质FixedUpdate。其他答案提到了如何以固定的interval, but that's slightly misleading. In reality, a script is passed a time in Time.deltaTime/ Time.fixedDeltaTime* 调用FixedUpdate,该固定的/ *不直接对应于两次调用之间的实际时间,而是对应于两次调用之间的模拟时间。

(* Time.deltaTime和[ Time.fixedDeltaTimeFixedUpdateUnity中被调用时具有相同的值,Unity能够确定当前调用是否Time.deltaTime在期间发起FixedUpdate并返回Time.fixedDeltaTime])

自然,Update由于性能变化,不能以恒定的方式调用相同的方法,也不能FixedUpdate。关键的区别是,每帧,如果FixedUpdate没有被足够频繁地调用以平均到两次调用之间的正确间隔,它会被调用多次(或者不被称为平均值太高)。这就是执行顺序上文档所指的意思,FixedUpdate可以在一个帧中多次调用:

... FixedUpdate:FixedUpdate通常比Update更常被调用。如果帧速率低,则每帧可以多次调用,如果帧速率高,则可能根本无法在帧之间调用...

由于其余的执行顺序和引擎的性质,这不会影响物理,但是您放入的其他任何东西 FixedUpdate都会受到影响,并且会引起问题。

例如,如果将AI处理放入内部,FixedUpdate则没有理由假定AI不会连续跳过多个帧的更新。此外,每次“ FixedUpdate”落后时,您的AI都会在处理诸如物理和玩家输入/运动之类的事情之前在一个帧中多次更新,这至少是在浪费处理,但也极有可能导致困难跟踪错误和不稳定的行为。

如果您需要以固定的间隔执行某项操作,请使用Unity提供的其他方法,例如CoroutinesInvokeRepeating

还有一点注意 Time.deltaTime以及何时使用:

描述Time.deltaTime的效果最简单的方法是每帧它改变了一些从单元,以单元每秒。例如,如果您的脚本中包含类似transform.Translate(Vector3.up * 5)Update 的脚本,则实际上是以每帧 5米的速率移动变换。这意味着,如果帧速率较低,则移动速度较慢;如果帧速率较高,则移动速度较快。

如果你采取同样的代码,并改变它transform.Translate(Vector3.up * 5 * Time.deltaTime),该对象被以5米的速度移动每秒。这意味着无论帧速率如何,对象都会每秒移动5米(但是帧速率越慢,对象的移动就会越快,因为它仍然每X秒移动一次相同的量)

通常,您希望每秒运动一次。这样,无论计算机的运行速度如何,您的物理/运动行为都将以相同的方式进行,并且在较慢的设备上不会出现奇怪的错误。

而且,在中使用它毫无意义FixedUpdate。由于上述原因,每次调用您将获得相同的值(固定更新时间步长值),并且对您的值没有任何作用。定义的运动/物理FixedUpdate已经可以以每秒单位为单位,因此您不需要它。


4

Update功能称为每帧。它的频率取决于计算机能够渲染图像的速度。在较慢的计算机上,Update呼叫频率比在较快的计算机上少。如果您执行基于时间的计算,则可以使用来Time.deltaTime对它们进行归一化,使用可以告诉您自上次Update调用以来已经有多长时间了(使用小孔)。
通常,您将Update用于执行与显示相关的任务(例如,更新UI元素)

FixedUpdate函数以固定间隔调用。无论图像刷新的频率多高,每秒FixedUpdate都会被调用1/Time.fixedDeltaTime一次。
您通常会FixedUpdate用来执行与游戏相关的任务(例如,更新物理效果)


这是乘以Time.delta时间的替代方法吗?是否有理由使用其中一个?
2015年

@Ben他们有两个不同的目标,您应该针对自己的工作使用正确的功能。
o0'。

@Lohoris对不起,我的意思是说有理由使用FixedUpdate而不是Update并将事情乘以Time.deltaTime使其独立于帧吗?

@本是的,精确。在渲染速度较慢的系统中,Update被调用的频率越来越低,因此您的模拟将遭受很大的损失。当仿真很简单时,您可能不会注意到,但是如果仿真不是简单的,它很容易被破坏。
o0'。

1
@Ben no:如果您希望模拟精确,则必须采取许多小步骤,而不是每次都随机增大或减小的大步。不,FixedUpdate的全部要点是它被调用了很多次,没有任何问题。
o0'。

2

来自:http : //unity3d.com/learn/tutorials/modules/beginner/scripting/update-and-fixedupdate

FixedUpdate中使用的时间步长不是可变的。

如果您的游戏开始滞后,那么当它赶上时,您不希望一次更新中的物理时间超过10秒,因此通常是在FixedUpdate中完成的,FixedUpdate是按固定间隔进行的。

例如:

Update(float elapsedSeconds)
{
  Position += Velocity * 34.23423; //Windows Update is self-important
}
FixedUpdate(float elapsedSeconds)
{
  Position += Velocity * 0.0166; //60fps
}

哪里:

Update(34.23423)

==

FixedUpdate(10.0)
FixedUpdate(10.0)
FixedUpdate(10.0)
//4.23423 + 5.76577 game-seconds later...
FixedUpdate(10.0)

我在回答中提到了这一点,但FixedUpdate实际上并不是以固定间隔调用的。的实际性质FixedUpdate是,如果您的游戏开始滞后,则将多个物理周期压缩为一帧;如果游戏进行得太快,则将其跳过,从而使平均值达到固定更新时间步长。Unity不是多线程的,因此没有办法保证以固定的间隔进行FixedUpdate调用(当一个FixedUpdate花费的时间太长时会发生什么)。即使是这样,也仍然几乎是不可能的。
Selali Adob​​or

大多数[Unity?]人都不知道Render / Update / FixedUpdate都是从单个回调方法中调用的,因此我将其概念化。谢谢你的努力!
2015年

2

Update被称为尽快。变量“ Time.deltaTime”设置为自上次调用以来经过的实际时间。如果滞后或类似原因使游戏变慢,Update则滞后结束后仍将仅被调用一次,其值很高deltaTime

FixedUpdate定期调用。它的调用频率永远不会超过“ Time.fixedDeltaTime”中指定的比率。如果滞后或类似原因使游戏变慢,FixedUpdate则会连续多次被调用以使游戏赶上来。Time.deltaTime设置为等于运行Time.fixedDeltaTimeFixedUpdate,但这只是为了使在两者之间轻松迁移代码变得容易。

通常,Update应将其用于可插值的行为以及FixedUpdate必须逐步计算的行为或依赖于此行为的行为,例如基于物理的运动。如果您正在Update沿线编写任何类型的循环,for(time=0;time<=deltaTime;time+=someStep)...则可能应该在FixedUpdate中进行。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.