Die anderen Antworten spekulieren nur, deshalb habe ich ein einfaches Unity-Projekt geschrieben und es eine Weile laufen lassen. Nach ein paar Stunden ist dies das Ergebnis:
UnityEngine.Time.time
verliert ziemlich schnell an Genauigkeit. Wie erwartet, springen die Werte nach 4-stündigem Ausführen des Spiels um 1 Millisekunde, und die Ungenauigkeit nimmt danach zu.
UnityEngine.Time.deltaTime
behält seine anfängliche Genauigkeit von unter einer Millisekunde, selbst nachdem Unity stundenlang ausgeführt wurde. Somit ist praktisch garantiert, dass deltaTime
von einem plattformabhängigen hochauflösenden Zähler (der in der Regel nach 10-1000 Jahren überläuft) abgeleitet wird. Es bleibt ein winziges Risiko, deltaTime
das auf einigen Plattformen immer noch an Präzision verliert.
Die Ungenauigkeit der Zeit ist ein Problem für alles, worauf es ankommt UnityEngine.Time.time
. Ein konkretes Beispiel ist die Rotation (z. B. einer Windmühle), auf der in der Regel basiert UnityEngine.Mathf.Sin(UnityEngine.Time.time*rotationSpeed)
. Ein noch größeres Problem wird _Time
explizit für Animationen von Shadern verwendet. Wie hoch muss die Ungenauigkeit sein, bevor sie spürbar wird? Die Genauigkeit von 20-30 ms (2 Tage) sollte der Punkt sein, an dem Personen, die sich des Problems bewusst sind und genau darauf achten, es bemerken werden. Bei 50-100 ms (5-10 Tage) werden sensible Leute, die nicht über das Problem Bescheid wissen, anfangen, es herauszufinden. Ab 200-300 ms (20-30 Tage) ist das Problem offensichtlich.
Bisher habe ich die Genauigkeit von _SinTime
, _CosTime
und noch nicht getestet Unity_DeltaTime
, daher kann ich dazu noch keinen Kommentar abgeben.
Dies ist das Skript, das ich zum Testen verwendet habe. Es ist an ein UI.Text
Element angehängt . In den Player-Einstellungen des Projekts kann das Projekt im Hintergrund ausgeführt werden. In den Qualitätseinstellungen ist VSync auf Every Second V Blank festgelegt:
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;
}
}
Wenn Sie sich über den 0.033203
Wert wundern , bin ich mir ziemlich sicher, dass dies tatsächlich der Fall ist 0.033203125
, für den eine binäre Gleitkommadarstellung vorliegt 00111101000010000000000000000000
. Beachten Sie die vielen 0
s in der Mantisse.
Problemumgehungen
Die meisten Genres benötigen keine Problemumgehung. Die meisten Spieler werden nicht einmal 100 Stunden lang ein Spiel spielen, weshalb es wirtschaftlich nicht rentabel ist, Geld zu investieren, um ein Problem zu beheben. Leider kann ich keine einfache, universelle Problemumgehung finden, die das gesamte Problem behebt, ohne einige wesentliche Nachteile mit sich zu bringen.