Inkonsistenter Jitter im iOS-Spiel

8

Ich arbeite an einem sehr einfachen vertikalen Scroll-Spiel für Unity iOS. Mein Spiel hat inkonsistente Jitter. Ich habe das Internet ausgiebig gesucht, ohne Glück zu suchen. Ich verwende Unity Version 5.3.4 f1.

Das Spiel

  • Ein Charakter fällt zusammen. Wir verwenden den Zeichencontroller von unity, um das Zeichen in Update() ( Time.deltaTime wird multipliziert) zu verschieben.
  • Die Kamera folgt dem Zeichen in LateUpdate() (mit Vector3.Lerp() folgt).
  • Da sich der Charakter nach unten bewegt, scheinen sich die Hindernisse nach oben zu bewegen.
  • Es gibt 1 gerichtetes Licht in der Szene, das für Echtzeit-Schatten eingerichtet ist. Die Schattenqualität ist Hoch und Hartschatten.
  • Es gibt keine starren Körper in der Szene. Und es gibt keine großen Spitzen im Profiler.
  • Wir haben eine sehr einfache Geometrie und sehr wenige Draw-Calls / Set-Pass-Aufrufe (durchschnittlich 7 Set-Pass-Aufrufe).
  • Wir haben konstante 60 fps.
  • Da wir auf iOS laufen, ist vSync standardmäßig On und kann nicht deaktiviert werden.

Das Problem

  • Die Hintergrundelemente / Hindernisse (Bäume, Felsen usw.) fangen ohne ersichtlichen Grund an zu zittern. Das Verhalten ist inkonsistent, manchmal wackelt es und manchmal nicht.
  • Auch wenn es nicht zittert, empfinden wir ein kleines Stottern, wenn der Benutzer per Berührung Eingaben vornimmt.

Was wir versucht haben

  • Wir haben alle Kombinationen von Update() , LateUpdate() , FixedUpdate() , Time.deltaTime Time.smoothDeltaTime , Lerp ausprobiert, um die Szene auf ein paar Würfel zu reduzieren und alle Collider und Trigger zu entfernen.
  • Wir haben bereits folgende Themen behandelt: Link1 Link2 , Link3 und unzählige andere Threads.
  • Anfangs lief unser Spiel mit den Standard 30 fps. Aber nach einigen Recherchen schien unser Problem auf den Unterschied zwischen "Frame Rate" und "Screen Refresh Rate" zurückzuführen zu sein. (Um dieses Problem zu verstehen, lesen Sie den folgenden LINK ). Da iOS-Geräte eine Bildwiederholfrequenz von 60 Hz haben, haben wir unsere Zielbildrate auf 60 gesetzt und unser Spiel hält konstant 60 fps.
  • Nachdem die Zielbildrate auf 60 eingestellt wurde, hat sich der Jitter verbessert, aber jetzt ist er inkonsistent.

Ich habe keine Ideen mehr. Jede Hilfe oder Zeiger wird sehr geschätzt.

Vielen Dank im Voraus.

    
Anas iqbal 03.08.2016, 17:11
quelle

3 Antworten

1

Dies könnte durch viele verschiedene Gründe verursacht werden, und ohne Code zu sehen, kann ich nur einige Vorschläge machen, die mir einfallen:

1. Float Point Genauigkeit Fehler

  • Fällt der Charakter ständig?
  • Tritt der Fehler auf, nachdem der Charakter für eine Weile gefallen ist?

Das würde auf einen Gleitkomma-Präzisionsfehler hinweisen. Anstatt das Zeichen fallen zu lassen, bewegen Sie die Objekte um das Zeichen von unterhalb der Bildschirmansicht zur oberen Bildschirmansicht, so dass alles in der Nähe des Ursprungs auftritt.

2. Häufig Instanziierung oder andere Verzögerungsspitzen

  • Werden Objekte instanziiert oder gebündelt?
  • Führen Sie lange Berechnungen durch?
  • Haben Sie viele for / foreach / while Schleifen?

Das Instanziieren führt zu einem Lag-Spike und einem Garabage-Effekt, der dazu führt, dass der Garbage Collector häufiger ausgeführt wird. Da die Framerate fest ist, sehen Sie bei einem langsamen Vorgang etwas Jitter.

Anstatt Objekte zu instanzieren und zu zerstören, wenn der Spieler eine gewisse Distanz zurücklegt, sollten Sie Instantiate einen Pool von GameObjects nach dem Laden der Szene mit gameObject.SetActive(false) inaktiv machen und sie in einer Liste, einem Array usw. speichern Wenn Sie Instatiate ein neues Objekt benötigen, nehmen Sie einfach eines aus dem Pool und ändern Sie es in Transform.position und gameObject.SetActive(true) , wenn es benötigt wird.

3. Müllsammler läuft oft

Dies ist wahrscheinlich kein Problem, aber ich erwähne es immer noch. Nimm diesen Beispielcode:

%Vor%

Jedes Mal, wenn Update ausgeführt wird, erstellt es neue Variablen und weist ihnen Speicher zu. Nächstes Mal Update runs, it creates new variables, and allocates more memory. Eventually, the memory usage sets off the garbage collector, which goes around and frees up the memory used by all the previous Update 'Funktionen. Stattdessen sollten Sie den Speicher am Anfang zuweisen und dann die Variablen wiederverwenden.

%Vor%

Um dies zu diagnostizieren, müssen Sie den Profil-Debugger anhängen und beobachten, ob der Jitter mit dem Garbage Collector konsistent ist.

Hoffentlich hilft dir hier etwas. Die beste Wahl für die Suche nach der Quelle des Jitters ist die Verwendung des Profilers. Hier ist die Anleitung für iOS:

  

Verbinden Sie Ihr iOS-Gerät mit Ihrem WiFi-Netzwerk (lokales / adhoc WiFi-Netzwerk)   wird vom Profiler verwendet, um Profiling-Daten vom Gerät an Unity zu senden   Editor). Aktivieren Sie das Kontrollkästchen "Autoconnect Profiler" im Unity-Build   Einstellungsdialog Verbinden Sie Ihr Gerät per Kabel mit Ihrem Mac, überprüfen Sie die   "Development Build" -Kontrollkästchen im Unity-Dialogfeld für die Build-Einstellungen und drücken Sie   "Bauen & amp; Ausführen "im Unity Editor. Wenn die App auf dem Gerät startet, öffnen Sie sie   Profilerfenster im Unity Editor (Window- & gt; Profiler).

Weitere Informationen: Das Profiler-Fenster

    
Xander Luciano 05.08.2016 22:28
quelle
1

Vielen Dank für Ihre Zeit.

  1. Nein, es handelt sich nicht um einen Gleitkommapräzessionsfehler.
  2. Wir erzeugen Objekte zur Laufzeit, aber als das Problem auftrat, wechselten wir zum Objekt-Pooling, aber es half nicht.
  3. Ich habe eine gründliche Profilerstellung vorgenommen, sogar Remote-Profiling auf einem Gerät und Garbage Collector war auch nicht das Problem.

Nach weiteren Recherchen bin ich auf ein BLOG POST , diese Leute standen vor einem ähnlichen Problem und die Lösung funktioniert in meinem Szenario.

Kurz gesagt, das Problem bestand darin, dass der Einheitsrahmen nicht mit der Rahmenzeichnungsrate des Geräts synchronisiert wurde. Wenn Unity zum Rendern des Frames etwas länger braucht, wartet die Geräte-Rendering-Schleife nicht auf das Ende der Einheit und zeichnet einen leeren Frame, was zu Jitter führt. Aber, wie ich im Titel des Posts "Inconsistent Jitter" gesagt habe, berichtet das Blog auch das selbe und so passiert es nicht die ganze Zeit.

Woher weißt du, dass es das gleiche Problem ist? Nun, Sie sehen Render Spikes im Profiler (obwohl wir sehr minimalistische Geometrie hatten). Es sieht eher so aus, als ob der Render verrückt wird.

Obwohl es im Blog mehr darum geht, Input zu verzögern, half es auch in meinem Szenario. Einige mögen nicht verstehen, wie genau ich dieses Problem lösen soll. Ich empfehle diesen POST , der eine sehr klare Lösung darstellt.

Beginnen Sie zu lesen, wenn der Benutzer "cgJames" in das KONVERSATION .

Ich hoffe, das hilft auch anderen.

    
Anas iqbal 08.08.2016 07:26
quelle
0

Ich habe in letzter Zeit über das gleiche Problem gestolpert. Genau ... Ein vertikaler Scroller in Unity mit einfachen Grafiken, der nur bei iOS eine inkonsistente Framerate aufweist, manchmal vielleicht im Zusammenhang mit der Eingabe, vielleicht nicht.

Wie auch immer, ich habe endlich herausgefunden, woher das Problem kommt. Versuchen Sie, die Rendering-Engine auf iOS von Metal zu OpenGL ES 2 oder 3 zu ändern.

Hoffe das löst auch dein Problem.

    
Damien Dessagne 05.04.2017 08:03
quelle

Tags und Links