Las otras respuestas solo especulan, así que escribí un proyecto simple de Unity y lo dejé correr por un tiempo. Después de un par de horas, este es el resultado:
UnityEngine.Time.time
pierde precisión con bastante rapidez. Como se esperaba, después de ejecutar el juego durante 4 horas, los valores saltan en 1 milisegundo, y la imprecisión aumenta después de eso.
UnityEngine.Time.deltaTime
mantiene su precisión inicial de submilisegundos incluso después de que Unity ha estado funcionando durante horas. Por lo tanto, está prácticamente garantizado que deltaTime
se deriva de un contador de alta resolución dependiente de la plataforma (que generalmente se desborda después de 10-1000 años). Sigue existiendo un pequeño riesgo que deltaTime
aún perderá precisión en algunas plataformas.
La inexactitud del tiempo es un problema para todo lo que depende UnityEngine.Time.time
. Un ejemplo específico es la rotación (por ejemplo, de un molino de viento), que generalmente se basa en UnityEngine.Mathf.Sin(UnityEngine.Time.time*rotationSpeed)
. Aún más de un problema es_Time
que se usa explícitamente para las animaciones de los sombreadores. ¿Qué tan alta debe ser la inexactitud antes de que comience a ser notable? La precisión de 20-30 ms (2 días) debe ser el punto donde las personas que conocen el problema y prestan mucha atención se darán cuenta. A 50-100 ms (5-10 días) las personas sensibles que no conocen el problema comenzarán a resolverlo. De 200 a 300 ms (20 a 30 días) el problema será obvio.
Hasta ahora no he probado la exactitud de _SinTime
, _CosTime
y Unity_DeltaTime
, así que no puedo comentar sobre ellos.
Este es el script que he usado para probar. Se adjunta a un UI.Text
elemento, la configuración del reproductor del proyecto permite que el proyecto se ejecute en segundo plano y VSync en la configuración de calidad se establece en cada segundo V en blanco:
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;
}
}
Si se está preguntando sobre el 0.033203
valor, estoy bastante seguro de que es realmente 0.033203125
, que tiene una representación binaria de coma flotante 00111101000010000000000000000000
. Observe los muchos 0
s en la mantisa.
Soluciones alternativas
La mayoría de los géneros no necesitan una solución alternativa. La mayoría de los jugadores ni siquiera juegan un juego durante 100 horas en total, por lo que invertir dinero para solucionar un problema que la gente solo notará después de unos pocos días hipotéticos de tiempo de juego continuo no es económicamente viable. Lamentablemente, no puedo encontrar una solución universal simple que solucione la totalidad del problema sin acarrear algunos inconvenientes significativos.