Auch Shader sind davon betroffen, was besonders problematisch ist, da man hier nicht einfach auf einen Double-Wert wechseln kann. Wenn du Shader über die Zeit animieren möchtest und deine App über mehrere Tage läuft, solltest du eine feste Schleife in Betracht ziehen, bei der die Modulo-Funktion den Wert nach Ende der Schleife wieder auf 0 zurücksetzt.
Verwende Time.timeAsDouble
Nutze Time.timeAsDouble
anstelle von Time.time
, um zeitbezogene Fehler nach längerer Laufzeit der App zu vermeiden. Wir hatten einmal eine App, die auf einer Maschine lief, die eigentlich täglich neu gestartet werden sollte. Aus irgendeinem Grund passierte das jedoch drei Tage lang nicht. Das Ergebniss war, dass einige Lichter merkwürdig blinkten, noch dazu war die Installation 400km entfernt.
Was ist passiert?
Zum Glück überwachen wir unsere Apps, wann immer es möglich ist, und stellten schnell fest, dass die Maschinen nicht wie geplant neu gestartet wurden. Wir konnten daher sofort vermuten, dass das Problem mit dem Timing zusammenhing. Zur Überprüfung simulierten wir einen hohen Time.time
-Wert, indem wir einen Tag in Sekunden hinzufügten: 24 * 60 * 60 = 86.400. Die Animation begann bereits zu stocken und wurde schlechter, je höher der Wert wurde.
In der betroffenen Methode verwenden wir trigonometrische Funktionen, um Pixel einer Textur zu animieren, die wiederum die Studiobeleuchtung steuert (indem die Textur auf einem zweiten Bildschirm angezeigt wird). Wie bekannt ist, haben Fließkommazahlen nur eine begrenzte Genauigkeit von etwa 7 Stellen. Für die meisten Anwendungsfälle reicht das aus—aber nur, wenn der Ganzzahlanteil nicht größer als 2 oder 3 Stellen wird. Sobald der Ganzzahlanteil jedoch 5 Stellen erreicht, nimmt die Genauigkeit der Nachkommastellen deutlich ab. In unserem Fall führte das zu sichtbaren Fehlern, da wir zusätzliche Offsets und Skalierungen auf diese Zahl angewendet haben.
Wie haben wir das Problem gelöst? Wir haben einfach auf einen Wert mit doppelter Genauigkeit umgestellt, indem wir Time.timeAsDouble
verwendet haben.
Wie lange funktioniert das zuverlässig?
Verwendest du einen Float für das Timing, könnte deine App nur ein bis zwei Tage stabil laufen, bevor visuelle Artefakte auftreten. Mit einem Double hingegen kann sie ein Jahr oder länger problemlos funktionieren. Aber wessen Spiele laufen überhaupt so lange?
Time-Variable bestenfalls vermeiden
Natürlich gibt es Situationen, in denen Floats gut funktionieren. In unserem Fall suchten wir jedoch nach einer schnellen, flexiblen Lösung. Eine Idee wäre, die Zeit in festen Intervallen zurückzusetzen. Dabei sollte jedoch kein sichtbarer Sprung entstehen.
Im Regelfall setzen wir Animationen so um, indem wir Variablen hoch- oder runterzählen und sie am Ende zurücksetzen.
float timerDuration = 3f;
float timer;
void Update()
{
timer -= Time.deltaTime;
if (timer <= 0f)
{
timer += timerDuration; // Reset by adding the value to catch overshoot (timer will be lower than 0)
}
//Animate here
}