Как сказано здесь :
Time.time
Время в начале этого кадра (только чтение). Это время в секундах с начала игры.
И, как я знаю, время сохраняется в float. Итак, мой вопрос: что произойдет, когда значение времени станет очень большим? Это может переполниться? Это потеряет точность и вызовет ошибки? Будет ли игра просто вылетать или как?
Ответы:
Существует реальный риск потери точности времени при использовании поплавка одинарной точности. .
Это все еще сохранит точность с точностью до секунды в течение 97 дней . Но в играх мы часто заботимся о точности порядка длительности кадра.
Значение времени с плавающей запятой одинарной точности в секундах начинает терять миллисекундную точность примерно через 9 часов .
Это уже не за пределами возможного для одиночной игровой сессии или оставления игры под управлением «АФК», пока вы на работе / в школе или спите. (Это одна из причин, по которой обычный способ проверить игру - это запустить ее на ночь и убедиться, что она по-прежнему играет правильно по утрам)
На современных консолях, где игры часто приостанавливаются и возобновляются между игровыми сессиями, а не закрываются полностью, неудивительно, что «один сеанс» с игровой точки зрения может превышать 9 часов времени выполнения даже при игре в короткие серии.
Предполагая, что Unity
deltaTime
вычисляется из источника времени с более высокой точностью, что подтверждается экспериментами Питера в другом ответе, полагаться наdeltaTime
тайминги в масштабе кадра относительно безопасно (просто будьте осторожны с накоплением очень больших длительностей путем суммированияdeltaTime
значений - добавляя небольшие приращения к большее число с плавающей запятой - это классический рецепт потери точности, даже если вы компенсируете хитрые алгоритмы ).Так как
fixedDeltaTime
сохраняет то же значение, которое вы установили, вместо того, чтобы динамически переходить от кадра к кадру, вы также можете поместить поведение, зависящее от времени, в FixedUpdate, чтобы получить более строгие гарантии согласованности.deltaTime
автоматически вернет соответствующую фиксированную дельту в этих методах. Несмотря на то, что между обновлениями фиксированных и кадровых кадров может быть частота биений, вы можете сгладить ее с помощью интерполяции .Чего вы хотите избежать, так это вычислять длительности, вычитая одну временную метку из другой . После нескольких часов игры это может привести к катастрофической отмене, что приведет к гораздо меньшей точности, чем в начале пробега. Если сравнение временных меток важно для ваших систем, вы можете сгенерировать собственное значение времени с более высоким разрешением, используя другие методы, например,
System.Diagnostics.Stopwatch
вместоTime.time
.источник
Максимальное значение с плавающей запятой составляет 3.40282347 * 10 ^ 38, что равно 10 ^ 31 годам при измерении в секундах (или 10 ^ 28 лет при измерении в миллисекундах). Поверь мне, это не переполнится.
Единственное, что может появиться - неточность. Но число с плавающей запятой одинарной точности имеет точность 7-8 десятичных цифр. Если использовать его для измерения секунд, он точен в течение 194 дней. Если измерять миллисекунды, то с точностью до 4,5 часов. Таким образом, это полностью зависит от точности, которая вам нужна, и вам может понадобиться найти альтернативные способы, если вам нужно быть с точностью до миллисекунды (что вы, вероятно, не делаете).
источник
Какая точность нужна вашей игре?
32-разрядное число с плавающей запятой имеет 24-битную точность. Другими словами, в момент времени t точность составляет ± 2 -23 × t. (Это не совсем правильно, но это близко, и точные детали не очень интересны.)
Если вам нужна точность в 1 мс, то через 1 мс ÷ 2 -23 = 8400 с = 2 ч 20 м 32-разрядное значение с плавающей запятой больше не допустимо. Точность 1 мс не является необходимой для большинства игр, но считается необходимой для музыкальных приложений.
Если ваша игра работает на мониторе с частотой 144 Гц и вам нужна графика с точностью до кадра, то через 1 ÷ 144 Гц ÷ 2 -23 = 58000 с = 16 ч 32-разрядное плавание больше не допустимо. 16 часов - это долгое время для запуска игры, но это немыслимо. Могу поспорить, что значительная часть из нас запускает игру в течение 16 часов за один раз - даже если только потому, что мы оставили игру запущенной и немного поспали. В этот момент обновления анимации и физики будут снижены до частоты ниже 144 Гц.
Если Единство
Time.deltaTime
рассчитывается по часам с более высокой точностью, то вы можете использовать это и при этом получить полную точность. Я не знаю, правда ли это или нет.Примечание
Игры и другие программы на Windows часто используют
GetTickCount()
чтобы выяснить время. Поскольку он использует 32-разрядное целое число для подсчета миллисекунд, он оборачивается примерно каждые 50 дней, если вы оставляете свой компьютер в таком состоянии. Я подозреваю, что многие игры будут зависать, зависать или работать неправильно, если вы играете в них с 50-дневной отметкой.Целые числа, такие как Windows
GetTickCount()
, рискуют переполниться, в то время как числа с плавающей точкой, как и UnityTime.time
, могут потерять точность.источник
Другие ответы только размышляют, поэтому я написал простой проект Unity и позволил ему какое-то время работать. Через пару часов это результат:
UnityEngine.Time.time
теряет точность довольно быстро. Как и ожидалось, после запуска игры в течение 4 часов значения подскочат на 1 миллисекунду, и после этого погрешность возрастет.UnityEngine.Time.deltaTime
сохраняет свою первоначальную точность до миллисекунды даже после нескольких часов работы Unity. Таким образом, практически гарантируется, чтоdeltaTime
он получен из зависящего от платформы счетчика высокого разрешения (который обычно переполняется через 10-1000 лет). Существует небольшой риск, которыйdeltaTime
все еще будет терять точность на некоторых платформах.Неточность времени является проблемой для всего, от чего зависит
UnityEngine.Time.time
. Одним конкретным примером является вращение (например, ветряная мельница), которое обычно основано наUnityEngine.Mathf.Sin(UnityEngine.Time.time*rotationSpeed)
. Еще одна проблема заключается в том,_Time
что явно используется для анимации шейдерами. Насколько высока должна быть погрешность, прежде чем она станет заметной? Точность 20-30 мс (2 дня) должна быть той точкой, на которую заметят люди, которые знают об этой проблеме и будут внимательно следить за ней. Через 50-100 мс (5-10 дней) чувствительные люди, которые не знают о проблеме, начнут ее выяснять. С 200-300 мс (20-30 дней) проблема станет очевидной.До сих пор я не проверял точность
_SinTime
,_CosTime
иUnity_DeltaTime
, таким образом , я не могу комментировать это.Это скрипт, который я использовал для тестирования. Он привязан к
UI.Text
элементу, настройки проигрывателя проекта позволяют запускать проект в фоновом режиме, а для VSync в настройках качества задано значение «Каждая секунда V Пусто»:Если вы задаетесь вопросом о
0.033203
значении, я уверен, что на самом деле0.033203125
это двоичное представление с плавающей запятой00111101000010000000000000000000
. Обратите внимание на множество0
символов в мантиссе.обходные
Most genres do not need a workaround. Most players won't even play a game for 100 hours total, so investing money to fix a problem people will only notice after a hypothetical few days of continuous playtime is economically not viable. Unfortunately I cannot come up with a simple universal workaround that fixes the entirety of the problem without carrying along some significant drawbacks.
источник