Інші відповіді лише міркують, тому я написав простий проект 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 пусте:
public class Time : UnityEngine.MonoBehaviour {
void Start () {
LastTime = (double)UnityEngine.Time.time;
StartTime = System.DateTime.Now;
LastPrintTime = System.DateTime.Now;
}
double LastTime;
System.DateTime StartTime;
System.DateTime LastPrintTime;
void Update () {
double deltaTimeError = (double)UnityEngine.Time.deltaTime - ((double)UnityEngine.Time.time - LastTime);
if (System.DateTime.Now - LastPrintTime > System.TimeSpan.FromMilliseconds(1000))
{
GetComponent<UnityEngine.UI.Text>().text = "StartTime: " + StartTime.ToLongTimeString()
+ "\nCurrentTime: " + System.DateTime.Now.ToLongTimeString()
+ "\n\nTime.deltaTime: " + UnityEngine.Time.deltaTime.ToString("0.000000")
+ "\nTime.time - LastTime: " + ((float)(UnityEngine.Time.time - LastTime)).ToString("0.000000")
+ "\nAbsolute Error: " + System.Math.Abs(deltaTimeError).ToString("0.000E0");
LastPrintTime = System.DateTime.Now;
}
LastTime = UnityEngine.Time.time;
}
}
Якщо вам цікаво 0.033203
значення, я впевнений, що насправді 0.033203125
це двійкове представлення з плаваючою комою 00111101000010000000000000000000
. Зауважте, що багато людей 0
у мантісі.
Обхідні шляхи
Більшість жанрів не потребує вирішення. Більшість гравців навіть не грають у гру за 100 годин, тому вкладати гроші, щоб вирішити проблему, люди помітять лише через кілька днів гіпотетичного безперервного відтворення, економічно не під силу. На жаль, я не можу придумати простий універсальний метод вирішення всієї проблеми, не усуваючи суттєвих недоліків.