Я собирался написать это как комментарий, но это оказалось довольно длинным, поэтому я превратил это в ответ.
Текущие ответы в основном правильные, но несколько упомянутых вещей вводят в заблуждение / неправильно.
Как правило, большинство задач, связанных с игровым процессом,Update
.
Например, вы не хотите опрашивать входные данные FixedUpdate
(не из-за производительности, а потому, что вызовы просто не будут работать правильно). ИИ падает в одну лодку.
Постоянно обновляемая физика - единственное задание, связанное с геймплеем, которое FixedUpdate
нужно использовать. Непрерывные / разовые вызовы таких вещей, как Physics.Raycast
или даже Rigidbody.AddForce
принадлежат Update
. Мое упоминание оRigidbody.AddForce
, казалось бы, противоречит тому, что может подразумеваться в документации, но ключ непрерывный против непрерывного.
Одна огромная причина, по которой принадлежит только непрерывная физика, FixedUpdate
- это фактическая природа FixedUpdate
. В других ответах упоминалось, как FixedUpdate вызывается в фиксированном interval, but that's slightly misleading. In reality, a script is passed a time in Time.deltaTime
/ Time.fixedDeltaTime
*, который не соответствует непосредственно фактическому времени между вызовами, а скорее моделируемому времени между вызовами.
(* Time.deltaTime
и Time.fixedDeltaTime
имеют одинаковое значение при вызове в FixedUpdate
[Unity может определить, произошел ли текущий вызов и Time.deltaTime
во время FixedUpdate
возврата Time.fixedDeltaTime
))
Естественно, один и тот же способ Update
не может быть вызван постоянным образом из-за разной производительности FixedUpdate
. Основное отличие состоит в том, что каждый кадр, если FixedUpdate
его не вызывали достаточно часто для усреднения до правильного интервала между вызовами, он вызывается несколько раз (или не вызывается, слишком высокое среднее значение). Это то, на что ссылаются документы по порядку выполнения, говоря, что FixedUpdate может вызываться несколько раз за кадр:
... FixedUpdate: FixedUpdate часто вызывается чаще, чем Update. Его можно вызывать несколько раз за кадр, если частота кадров низкая, и его вообще нельзя вызывать между кадрами, если частота кадров высокая ...
Это не влияет на физику из-за характера остальной части порядка выполнения и движка, но почти все, что вы вставляете в FixedUpdate
будет затронуто добавите, и это вызовет проблемы.
Например, если вы поместите обработку AI внутри FixedUpdate
нет никаких оснований предполагать, что ИИ не будет пропускать обновления для нескольких кадров подряд. Кроме того, каждый раз, когда `FixedUpdate отстает, ваш ИИ будет обновляться несколько раз в одном кадре до того, как будут обрабатываться такие вещи, как физика и ввод / движение игрока, что, по крайней мере, является пустой тратой обработки, но также весьма вероятно, что вызовет сложный процесс. чтобы отследить ошибки и неустойчивое поведение.
Если вам нужно что-то делать с фиксированным интервалом, используйте другие методы, которые предоставляет Unity, такие как Coroutines
иInvokeRepeating
.
И небольшая заметка о Time.deltaTime
когда и как его использовать:
Самый простой способ описать эффект Time.deltaTime - это изменение числа от единицы на кадр до единицы в секунду . Например, если у вас есть скрипт с чем-то вроде transform.Translate(Vector3.up * 5)
Update, вы по существу перемещаете преобразование со скоростью 5 метров на кадр . Это означает, что если частота кадров низкая, движение будет медленнее, а если частота кадров высокая, движение будет быстрее.
Если вы возьмете тот же код и измените его на transform.Translate(Vector3.up * 5 * Time.deltaTime)
, объект будет перемещаться со скоростью 5 метров в секунду . Это означает, что независимо от частоты кадров, объект будет перемещаться на 5 метров каждую секунду (но чем медленнее частота кадров, тем выше будет движение объекта, так как он все равно перемещается на одну и ту же величину каждые X секунд)
В общем, вы хотите, чтобы ваше движение было в секунду. Таким образом, независимо от скорости компьютера, ваша физика / движение будет вести себя одинаково, и у вас не будет странных ошибок, появляющихся на медленных устройствах.
И нет смысла использовать его в FixedUpdate
. Из-за того, что я упомянул выше, вы будете получать одно и то же значение при каждом вызове (значение «Фиксированное время обновления»), и оно ничего не изменит с вашими значениями. Движение / физика, определенные в FixedUpdate
, уже будут в единицах в секунду, поэтому вам это не нужно.
Update
вызывается все реже и реже, и ваша симуляция сильно пострадает от этого. Вы можете не заметить, пока симуляция проста, но она легко сломается, когда это не так.От: http://unity3d.com/learn/tutorials/modules/beginner/scripting/update-and-fixedupdate
Шаг по времени, используемый в FixedUpdate, не является переменным.
Если ваша игра начинает зависать, когда она догоняет, вам не нужно> 10 секунд физики в одном обновлении, поэтому обычно это делается в FixedUpdate, который вызывается с фиксированным интервалом.
Например:
Где:
источник
FixedUpdate
самом деле не вызывается с фиксированным интервалом. Фактическая сущностьFixedUpdate
состоит в том, чтобы сжать несколько циклов физики в один кадр, если ваша игра начинает отставать, и пропустить циклы, если она идет слишком быстро, так что среднее значение подходит к Фиксированному временному шагу обновления. Unity не является многопоточным, поэтому невозможно было бы гарантировать вызовы FixedUpdate с фиксированным интервалом (что происходит, когда один FixedUpdate занимает слишком много времени). Даже если бы это было так, вероятно, все равно было бы почти невозможно.Update
называется как можно быстрее. Переменная Time.deltaTime устанавливается на фактическое количество времени, прошедшее с момента последнего вызова. Если задержка или что-то подобное замедляет игру,Update
она все равно будет вызвана только один раз, когда задержка закончится, с высоким значениемdeltaTime
.FixedUpdate
вызывается через равные промежутки времени. Он никогда не будет вызываться чаще, чем соотношение, указанное в Time.fixedDeltaTime. Если задержка или что-то подобное замедляет игру,FixedUpdate
она будет вызываться несколько раз подряд, чтобы игра могла наверстать упущенное.Time.deltaTime
устанавливается равным,Time.fixedDeltaTime
прежде чемFixedUpdate
выполняется, но это просто выдумка, чтобы облегчить перенос кода между ними.Как правило,
Update
следует использовать для интерполируемого поведения иFixedUpdate
для поведения, которое должно вычисляться поэтапно или зависеть от того, что делает, например, движения, основанного на физике. Если вы пишете какой-либо циклUpdate
вдоль строк,for(time=0;time<=deltaTime;time+=someStep)...
то вам, вероятно, следует делать это в FixedUpdate.источник