Wie mache ich den Gameloop unabhängig vom Rendern? Simulation mit 600 ticks pro Sekunde aber nur 60 mal pro Sekunde Rendern

  • Hallo Leute,

    für eine Simulation muss mein gameloop so schnell wie möglich sein. Ich will das Ergebnis aber nur mit 60fps rendern.

    Momentan schaffe ich 600 ticks pro Sekunde was aber dann auch heisst, dass 600 mal pro Sekunde gerendert wird.
    Mein Gedanke ist nun, dass ich wohl mehr ticks pro Sekunde im gameloop schaffe, wenn das Rendern nur mit 60fps erfolgt.


    Hat irgendwer eine Idee wie ich das hinbekomme?


    Viele Grüße :*

    Alex

    • Offizieller Beitrag

    Hi, bist du sicher dass das so eine gute Idee ist ?


    Ein Tick ist nicht dasselbe wie ein Frame, und theoretisch kann ein Tick sogar öfter als ein Frame ausgeführt werden.

    Wenn dein Spiel lagt (aus welchem Grund auch immer), wird in dieser Zeit auch kein Tick ausgeführt.

    Ticks werden nur ausgeführt, wenn Frames gezeichnet werden.

    Ich weiß nicht, was du vorhast; unter Umständen ist das genau so gewollt.

    Ich frage mich, ob du das, was du umsetzen möchtest, auch ohne Ticks erreichen kannst?

    Durch die Tick-Lösung hängst du auf jeden Fall stark von Frames ab.


    Auf einem Rechner mit schlechterer Grafikkarte, würden dann auch weniger Ticks ausgeführt werden da die GPU weniger FPS zeichnet.
    Das kann zu ziemlichen Performance einbrüchen führen.


  • Hi, ok ich erklär das mal.

    Ich habe eine Simulation programmiert, die so oft wie möglich pro Sekunde ihre Rechenergebnisse an ein anderes Programm schicken soll. Wenn ich das Rendern ausschalte schafft sie das etwa 1500 mal pro Sekunde. Der User soll aber noch sehen was in der Simulation grundsätzlich passiert also muss ich das Rendern einschalten. Wenn ich das mache, dann sinkt diese Rate auf 600 pro Sekunde ab. Ein Rechendurchgang (also ein tick) ist dann ein Frame. Die Grafikkarte schickt dann das Bild 600 mal pro Sekunde an den Bildschirm.
    Mein Gedanke ist nun einfach nicht jeden tick zu Rendern (nur mit 60fps). Dann besteht die Hoffnung dass die Simulation wieder schneller wird.


    Danke schon mal!!

  • Ich glaube, du denkst da falsch. Nicht jeder Tick ist nicht ein Frame. Wenn ich mich nicht irre, dann ist die Engine standardmäßig auf 60 Frames eingestellt. Zumindest war das mal eine Zeitlang so.

    Was genau willst du denn überhaupt berechnen und anzeigen lassen? Wenn du irgendwelche Cryptos minen willst, wofür es mit Sicherheit besseres geben würde als die Unreal Engine, oder was auch immer, und einfach nur eine Statusanzeige haben möchtest, dann mach das doch über Text. Text braucht eigentlich kaum Rechenleistung.

    Und ich weiß gar nicht, ob das geht, aber es gibt bestimmt auch eine Möglichkeit eine Konsolenausgabe zu verwirklichen.

    • Offizieller Beitrag

    Ein Rechendurchgang (also ein tick) ist dann ein Frame.

    Nein genau das ist ein Tick eben nicht. Ein Tick ist nicht ein Frame sondern ein Tick ist eine Zeitspanne die innerhalb eines Frames passiert


    Ich mach mal ein paar Beispiele damit du die Unterschiede verstehst.


    1.Nehmen wir mal an du hättest einen Timer: Ein Timer Zählt einfach nur die Zeit. Einem Time ist die Framerate völlig egal. Er tut beispielsweise etwas alle 10 Sekunden


    2. Nehmen wir an du würdest ein Propeller jeden Tick einmal um 1 grad drehen. Das würde bedeuten das sich dein Ventilator einmal Pro Frame um 1 Grad dreht. (Wichtig ein Frame nicht aber nicht nur jede Sekunde gezeichnet sondern mindestens 60 mal pro Sekunde. Wohl eher noch öfter)


    Mal angenommen deine Grafikkarte zeichnet 360 Frames pro Sekunde, dann würde sich ein Propeller pro Sekunde um 360 Grad drehen.


    Jetzt aufgepasst:


    Mal angenommen du hast nur eine Grafikkarte die NUR 180 Frames pro Sekunde schafft, dann würde sich dein Ventilator auch nur um 180 grad pro Sekunde drehen.


    Mal angenommen du hast ne bessere Grafikkarte die 720 Frames pro Sekunde schafft, dann dreht sich ein Ventilator um 720 grad pro Sekunde drehen.


    oder du bekommst pro Tick einen Euro, dann würde der Spieler der die beste Grafikkarte hat am meisten Geld bekommen.


    Ein Delay durch einen Tick wirkt sich deswegen auf jedem Rechner anderst aus.


    . Die Grafikkarte schickt dann das Bild 600 mal pro Sekunde an den Bildschirm.

    Wie gesagt wenn dein Rechner lagt und der Lag 5 Sekunden dauert wird jeder Frame nur alle 5 Sekunden gezeichnet, das bedeutet deine GPU schickt alle 5 Sekunden 600 Bilder an eine GPU womit du deine GPU ziemlich bombadierst.

    Außerdem sind das unnötige Drawcalls. Du schickst ununterbrochen Befehle an deine CPU bzw GPU.


    Die Unreal entschiedet ja auch selbst wer Jobs abarbeiten darf. Soll es schnell gehen, macht das die GPU muss es nicht so schnell gehen, macht das die CPU. Wenn du aber GPU lastige Prozesse hast, dann kann es vorkommen dass dein GPU auf Vollgas läuft und sich deine CPU langweilt.


    Hoffe du verstehst was ich meine.

  • Wenn du es schon so detailiert darstellst, dann solltest du aber noch den Unterschied zwischen Tick und Deltatime mit reinnehmen.

    Denn, Deltatime hat ja auch ihre Existenzberechtigung. Mit Deltatime kannst du nämlich dafür sorgen, dass der besagte Ventilator immer eine Sekunde pro Umdrehung benötigt, unabhängig von der Geschwindigkeit des Rechners. Um genau zu sein, ist Deltatime die Zeitspanne zwischen zwei Frames.

    Diese kannst du dann wiederum benutzen, um zum Beispiel eine Bewegung, zu berechnen, die immer gleich ist.

    Nehmen wir mal ein Beispiel, bzw. bleiben bei dem Ventilator. Wenn du den Ventilator rotieren lassen willst, dann kannst du halt über den Tick gehen und bei jedem Tick um 1 Grad oder so drehen. Das führt aber dazu, bei langsamen Rechnern, nehmen wir an, 20 Ticks pro Sekunde, dann braucht den Ventilator halt 18 Sekunden für eine Umdrehung. Also, doch ziemlich langsam.

    Bei einem schnellen Rechner hättest du vielleicht 2.000 Ticks pro Sekunde und der Ventilator bräuchte 0,18 Sekunden pro Umdrehung.

    Jetzt kommt die Deltatime. Je niedriger die Anzahl der Ticks, umso höher wird Deltatime und umgekehrt.

    Nun kannst du halt festlegen, du möchtest eine vollständige Umdrehung innerhalb von 0,18 Sekunden, unabhängig von der Leistung des Rechners. Also gibst du für die Rotation folgendes vor. Winkel = (360 / 0.18) * DeltaTime. Ich hoffe, ich habe mich bei der Formel jetzt nicht vertan.

    Aber, du siehst hier ja schon, dass dadurch der Winkel variabel wird. Das führt dazu, dass der Ventilator zwar immer 0,18 Sekunden für eine Umdrehung benötigt, aber dafür die Zwischenwinkel mal größer und mal kleiner sind.

    Zusammengefasst. Mit Deltatime kannst du angeben, welche Strecke in welcher Zeit und das bleibt dann immer gleich.

  • Nein nein Leute. Vielleicht hab ich mich da falsch ausgedrückt. Sorry.
    Also: In meinem Programm bewege ich ein CAD Modell einer Maschine synchron zu einer baugleichen wirklichen Maschine. Die Aufgabe ist es nun so oft wie möglich pro Sekunde zu überprüfen ob eine Kollision droht um dann die reale Maschine vor eine Kollision zu schützen.

    Mein Programm schafft es 1500 mal pro Sekunde zu prüfen ob eine Kollision droht oder nicht und schickt die Info an die reale Maschine. Droht eine Kollision, schaltet sich die Maschine ab. Diese 1500 Rechendurchgänge pro Sekunde schaffe ich, wenn ich das Rendern ausschalte. Wenn ich das Rendern einschalte, dann schaffe ich nur noch 600 Rechendurchgänge pro Sekunde. Das liegt daran, dass Unreal pro Rechendurchgang einmal die Grafik rendert. Der Rechendurchgang muss warten bis gerendert wurde und das bremst das Programm eben auf 600 Rechendurchgänge pro Sekunde runter.
    Mein Gedanke ist nun das Rendern unabhängig vom Rechendurchgang zu machen. Das Programm soll so oft wie möglich pro Sekunde auf Kollisionen testen aber nur 60 mal pro Sekunde rendern.

  • Ich glaube, du verstehst es nicht richtig. Die Berechnung ist unabhängig vom Rendern. Allerdings benötigt der Rendervorgang logischerweise ebenfalls Renderkapazitäten, was die Berechnungen natürlich langsamer macht.

    Deswegen hast du wiederum natürlich auch nicht ganz unrecht, denn natürlich ist die Engine, salopp gesagt, so ausgelegt, dass die Darstellung und die Berechnungen ein sinniges Bild ergeben. Aber was erwartest du von einer Spieleengine?

    P.S. Das einzige, was mir vielleicht dazu einfallen würde, ist, dass du eine C++-Routine schreibst, oder auch eine Funktion mit BP, die schlicht deine Berechnungen alleine macht, immer und immer wieder, und bei bestimmten Auslösern über einen Eventdispatcher dann halt die Darstellung anzeigt. Ob das funktioniert weiß ich allerdings auch nicht, weil, das habe ich noch nie ausprobiert.

    Allerdings kommt mir das ganze Projekt sehr merkwürdig vor. Weil, wenn du einmal ein simuliertes Modell mit dem realen Modell synchron laufen lassen willst, warum, warum sendest du dann ständig Daten an das reale Modell und nicht nur wichtige Daten, zum Beispiel, wenn eine Kollision droht?

  • Hallo


    Das ist ja mal ein interessantes Projekt.

    Mit t.maxFps kannst du die FPS auf 60 setzen oder in den Settings.


    Dann kannst du überlegen, ob du die Simulation in mehrere einzelnen Threads packen kannst.

    Das wird zum Beispiel beim Animation BP so gemacht.


    Alternativ und deutlich einfacher kannst du es vermutlich auch mit der Tick Group deines relevanten Actors umsetzen, also mit einer custom tick group.

    So kannst du eine Gruppe von Actors maximal priorisieren. Das bedeutet mehrere Ticks pro Frame, statt wie normalerweise einmal zu irgendeinem Zeitpunkt im Frame.


    Hoffe, das hilft dir weiter.

    Gruss

  • Tomarr
    - Wenn der Rendervorgang unabhängig von den Berechnungen läuft, und ich wie besagt 600 Rechendurchgänge pro Sekunde schaffe, wie oft erfolgt dann das Rendern pro Sekunde? Kann ich das einstellen (idealerweise 60 mal pro Sekunde).
    - In einem anderen Forum hab ich eine andere Aussage gefunden: "while the game logic and the renderer execute on a separate thread they do not operate at independent frame rates. Every render frame corresponds directly to a game logic frame". Und das ist mein Problem
    - Das Projekt ist nicht sehr merkwürdig :) Ich sende nur wichtige Daten an die Maschine, nämlich so oft wie möglich pro Sekunde ob eine Kollision droht oder nicht.




    Phoenix-100
    - hui das ist natürlich schon was Ausgewachsenes: die Framerate auf 60fps stellen und die komplette Simulation schneller ticken. Das betrifft nicht nur actors sondern auch den level blueprint. Ich glaub das wird mir zu steil ....
    Aber ich überleg mal in die Richtung!



    Dankeschön!!

  • Es kommt ja immer darauf an, wo und wie du die Berechnung anstellst.

    Sagen wir mal, du hast eine Schleife, die zählt eine Variable ständig um eins hoch, dann wird es unabhängig vom rendern stattfinden, auch in der Unreal Engine. Wenn du jetzt allerdings die Renderdarstellung abhängig von der Berechnung machst und umgekehrt, dann muss die Berechnung sich natürlich mit der Renderdarstellung synchronisieren und wird dann abhängig vom Rendern. Und du sagst ja selber, wenn du Rendern ausschaltest, dann hast du eine wesentlich höhere Berechnungsrate. Das wäre ja nicht so, wenn Rendern und Berechnung komplett abhängig wären.

    Das bedeutet, wenn du diese Abhängigkeit hergestellt hast und du die BPS runtersetzt, auf zum Beispiel 60, dann könnte es natürlich sein, dass du auch die Berechnung verlangsamst. Kannst du aber ja ausprobieren, siehe meinen ersten Beitrag mit den Projekteinstellungen.

    Eine andere Möglichkeit wäre halt mit einem Eventdispatcher. Zum Beispiel könntest du eine Variable bei jedem Rechendurchgang um 1 hochzählen und dann alle 60 Durchgänge sagen, er soll dir grafisch halt die aktuelle Situation darstellen.

    Genauso könntest du es natürlich auch ereignisabhängig machen. Zum Beispiel, dass er dir nur grafisch den Status darstellt, wenn laut Berechnung etwas schiefgelaufen ist.

    Allerdings, wie so oft im Forum. Ohne Code kann man das immer nur sehr theoretisch erörtert werden. Wobei in deinem Fall eine genauere Erläuterung deines Versuchsaufbaus vielleicht hilfreich wäre und selbst dann hat wahrscheinlich noch niemand die Unreal Engine so benutzt. ^^