Published using Google Docs
FixedUpdateDiscuss
Updated automatically every 5 minutes

Особенности симуляции реального времени в Unity3D

Валерия Пудова
4 декабря 2020

Введение

Анализ особенностей программирования процессов реального времени в дискретной системе симуляции на примере Unity3D.  

Цель документа подтвердить или опровергнуть то, что методы Update или FixedUpdate не гарантируют точность внутренних часов (class Time). Документ должен ответить на два вопроса:

Теперь сформулируем вопросы более конкретно и ответим на них:

Вызывается ли FixedUpdate в реальном времени?

Если fixedDeltaTime равна 10ms. Будет ли метод вызываться  строго каждые 10 миллисекунд?

Не будет. Время обновление физики time for physics update TFPU в зависимости от ситуаций может быть меньше или больше чем fixedDeltaTime.

Будет ли гарантия того что за реальное время (T) метод  FixedUpdate будет вызван согласно выражению?

Nfu = T / Fdt

где:
        
Nfu         количество вызовов FixedUpdate
        
T         реальное время
        
Fdt          значение fixedDeltaTime

Не будет. Ибо в ситуации когда TFPU больше чем fixedDeltaTime, то  физический движок не сможет достичь времени T даже если загрузит процессор эксклюзивно. Так как физика пытается догнать реальное время, и непрерывно выполняется Nfus раз подряд, до тех пор пока fixedTime меньше чем T, то это приведет к замораживанию рендеринга на неопределенное время  (Frame-skipping mode).        

Для того чтобы минимализировать этот эффект существует параметр maximumDeltaTime.  Он не позволяет физике выполняться подряд более заданной величины. И когда произведение fixedDeltaTime на Nfus достигнет значение более или равно чем maximumDeltaTime тогда  физика "откладывает" обновление "пропуская" фрагмент реального времени (Wall of molasses mode).

Иначе говоря время в виртуальном мире не может быть гарантировано синхронным с реальным временем. Об этом четко написано в руководстве Unity3D:

If frame will take longer than specified value, then less physics and other fixed frame rate updates will be performed. That will temporarily slow down the gameplay, but will allow frame rate to catchup avoiding nasty  stuttering.

Может ли Time.time  быть разсинхронизровано с Time.fixedTime?

Не может. Ибо один зависит от другого, что может быть описано  упрощенной формулой.

Tvn =  Tvn-1 + Fdt * Nfus;

Где:
        T
vn        время в кадре n
        Tvn-1        время в кадре n-1
        
Fdt          значение fixedDeltaTime
        Nfus         количество вызовов FixedUpdate между Tn  и Tn-1

Вывод:

Unity3D не манипулирует значением timeScale, и не замедляет время. Вместо этого  когда TFPU больше чем Fdt и если Fdt * Nfus больше чем maximumDeltaTime, то Unity3D принудительно прерывает обновление физики отдавая предпочтение другим операциям (например рендеринг). Это косвенно замедляет время внутри Unity3D.

Когда системы испытывает нехватку вычислительных ресурсов используется один из двух возможных сценариев (иногда называемые).

Тоже самое справедливо и для других движков.

Ссылки:

[1] Timesteps and Achieving Smooth Motion in Unity