(Unity) Optimierte Netzwerklösung für viele sich bewegende Objekte

8

Ich habe derzeit ein ziemlich ehrgeiziges Projekt durchgeführt. Kurz gesagt, es ist ein Echtzeit-Multiplayer-Strategiespiel mit Bakterienmechanik.

Im Wesentlichen habe ich zwei entfernte Spieler in der Umgebung, die bakterienähnliche Einheiten hervorbringen können, die sich gegenseitig angreifen und vermehren und sich selbst duplizieren, bis ein Ressourcenlimit erreicht ist. Dies führt häufig dazu, dass mehr als 200 Spielobjekte auf dem Bildschirm gerendert werden, jedes mit seinem eigenen Status und seiner eigenen Bewegung. Das hört sich schlecht an, aber das lokale Gameplay gegen einen Bot ist tatsächlich sehr gut, und ich habe es geschafft, es ziemlich performant zu machen.

Das Problem tritt jedoch auf, wenn ich versuche, dieses Spiel zu vernetzen. Ich habe bereits versucht, diesem Handbuch zu folgen, um diese Funktion zu implementieren: http://www.paladinstudios.com/2013/07/10/how-to-create-an-online-multiplayer-game-with-unity/

Dies erzeugt selbst bei bester Latenz ein ziemlich langsames, unangenehmes Spielerlebnis. Dies wird wahrscheinlich dadurch verursacht, dass Bewegungsdaten für Hunderte von Einheiten übertragen werden müssen.

Die Frage, die ich stelle:

Wie kann ich die Vernetzung und Synchronisation vieler sich bewegender Einheiten zwischen zwei Clients optimieren?

Ich habe bereits über einen Weg nachgedacht, dies zu tun. Nachdem sie eine Einheit erzeugt haben, bewegen sie sich nur in eine Richtung, bis sie auf etwas treffen - vielleicht kann ich nur synchronisieren, wenn Einheiten erzeugt werden und wenn sie mit einem anderen Objekt interagieren? Hätte das viel Nutzen? Was ist der ideale Weg, um dies umzusetzen?

Vielen Dank im Voraus für die Antworten!

Rachel Cabot
quelle
Ist ein Lockstep-Modell wahrscheinlich das, was ich brauche? Clintonbrennan.com/2013/12/lockstep-implementation-in-unity3d
Rachel Cabot
Ich bin hinter einer Firewall und kann nicht auf das von Ihnen verknüpfte Beispiel zugreifen. Haben Sie jedoch versucht, nur die Objekt-ID-, Positions- und Geschwindigkeitsvektoren für jeden Frame zu serialisieren? Je nachdem, wie clever Sie mit dem Serialisierungsalgorithmus sind, können Sie die Statusinformationen auf 7 Byte pro Objekt reduzieren. Wenn Sie sicherstellen, dass der Client eine fehlende ID aus dem Update als Tod und eine neue als Spawn annimmt, sollten Sie keine Probleme haben.
Stephan

Antworten:

1

Bei mehr als 200 sich bewegenden Objekten möchten Sie auf jeden Fall Ihr Spiel sperren. Mit Lockstep kommt die Notwendigkeit von Determinismus, aber das sollte für Bakterien nicht zu schwer sein (was mit Kreis-Kreis-Kollisionen simuliert werden kann).

Wenn Ihnen mein schamloser Self-Plug nichts ausmacht und Sie ein Beispiel mit der Netzwerk- und Simulationslogik eines Lockstep-Spiels wünschen, sehen Sie sich dieses Asset kostenlos an: https://www.assetstore.unity3d.com/en/#!/ Inhalt / 36206 . Leider enthält diese Version nicht den gesamten Quellcode, aber Sie können ihn gerne mit meinem Segen hacken;). Hier ist ein Video eines frühen Tests von DPhysics: https://www.youtube.com/watch?v=NEzOghxfMdU .

Der Kern von Lockstep ist die Synchronisierung der Eingabe anstelle der Ausgabe. Dies liegt daran, dass bei einer synchronen Simulation nur die Eingaben anderer Clients nichts über alle Clients wissen. Der Artikel, den Sie in Ihrem Kommentar verlinkt haben, erklärt es ziemlich gut. Ich bin mir nicht sicher, wie ausführlich ich Lockstep erklären soll, also werde ich es hier abschneiden und diese Antwort erweitern, wenn Sie weitere Fragen haben.

Update: Stellen Sie sich einen autorisierenden Server vor, außer dass der Server anstelle des Spielstatus Eingaben sendet. Da jeder Spieler den Spielstatus aus Eingaben für sich selbst erstellen kann, muss der Server den Spielstatus nicht verteilen.

JPtheK9
quelle
1
Dieser Ansatz kann möglicherweise zu einer De-Synchronisierung führen, selbst wenn alles deterministisch ist, nur aufgrund der Latenz zwischen den gemeinsam genutzten Eingaben. Nehmen Sie als Beispiel ein Spiel, in dem Spieler versuchen, die Bewegung eines Objekts durch Platzieren von Wänden zu blockieren. Auf dem Bildschirm eines Spielers hat er möglicherweise die Platzierung korrekt festgelegt, und das Objekt ist blockiert. Die Replikation auf den anderen Client kann jedoch zu spät erfolgen, und sobald die Wand platziert ist, hat das Objekt diesen Ort bereits passiert. Abhängig von Ihrer Spielmechanik müssen Sie möglicherweise weiterhin regelmäßig "Big Picture" -Updates senden, um Clients erneut zu synchronisieren.
Acidictadpole
Guter Punkt. Es besteht kein Desynchronisierungspotential, wenn dies korrekt durchgeführt wird. Wenn ein Paket übersehen wird oder sehr spät kommt, kann der Client nicht zum nächsten Frame übergehen. Er muss warten, bis das Paket eintrifft, um den aktuellen Frame auszuführen. Frames können mit ganzen Zahlen dargestellt werden. Der Server verteilt Pakete, die mit einer Ganzzahl für jeden Frame markiert sind.
JPtheK9
Überzeugen Sie sich selbst von der Netzwerk- und Rahmenlogik.
JPtheK9
1
@ JPtheK9 "Er muss warten, bis das Paket eintrifft, um den aktuellen Frame auszuführen." Und was ist, wenn das Paket nie kommt?
Stephan
Fordern Sie einen neuen an.
JPtheK9