Jump to content
Unity Insider Forum

Jolinah

Members
  • Posts

    33
  • Joined

  • Last visited

  • Days Won

    7

Jolinah last won the day on April 4 2020

Jolinah had the most liked content!

About Jolinah

  • Birthday 11/19/1983

Contact Methods

  • Website URL
    http://www.michael-zehr.ch

Profile Information

  • Gender
    Male

Recent Profile Visitors

925 profile views

Jolinah's Achievements

Advanced Member

Advanced Member (3/3)

9

Reputation

  1. Hallo Ich habe vor kurzem Substance Painter abonniert und zum Test ein kleines Schwert modelliert und danach in Painter bemalt. Ist jetzt nicht perfekt, aber ich dachte ich könnte es ja trotzdem mal hier reinstellen, falls es jemand gebrauchen kann. Wenn gewünscht, könnte ich den Rost entfernen oder im unteren Teil auch noch etwas Rost hinzufügen. Sword.unitypackage
  2. Hallo, Zuerst zur zweiten Frage, da die etwas einfacher zu beantworten ist: Im neuen UNet (mit der High Level API) gibt es Server, Host und Client. Ein Server ist ein dedizierter Server, ein Host ist dagegen ein Server mit einem lokalen Spieler. Das einfachste Setup ist ein GameObject mit einem angehängten NetworkManager-Script und zusätzlich dem NetworkManagerHUD-Script zu erstellen. Dann wird ein Prefab mit einem NetworkIdentity-Script benötigt, welches man beim NetworkManager als Spielerobjekt zuweist. Ausserdem muss man noch eine Online- und eine Offline-Szene erstellen und dem NetworkManager zuweisen. Sobald man dann das Spiel startet und Server/Host im GUI auswählt, wird die Online-Szene geladen und beim Host das Spieler-Objekt erzeugt (beim Server natürlich nicht, da es noch keinen Client gibt). Und nun zur anderen Frage: Grundsätzlich ist UNet ein Server/Client-Modell und es ist durchaus möglich die Autorität dem Server zu überlassen. In Tutorials zeigt und empfiehlt Unity jedoch meistens das Modell mit der Client-Autorität, vermutlich weil es für Anfänger halt wesentlich einfacher ist. Die Server-Autorität ist wirklich ein komplexes Thema (zumindest bei schnellen Action-Games). In Spielen wie Half-Life etc. wird meistens die Kombination von Client Prediction (auf dem Client) und Lag Compensation (auf dem Server) angewendet. Es gibt dazu auch von Valve einen Artikel, den ich sehr empfehlen kann: https://developer.valvesoftware.com/wiki/Latency_Compensating_Methods_in_Client/Server_In-game_Protocol_Design_and_Optimization Grob zusammengefasst: Der Client sammelt tatsächlich alle Inputs zusammen mit der deltaTime und der absoluten Zeit bzw. Netzwerkzeit. Server und Client teilen sich die exakt gleiche Physik und Update-Logik. Der Client führt die Physik für jedes Input sofort lokal aus (Spieler bewegt sich lokal ohne Lag). Ausserdem schickt er diese Inputs an den Server, welcher die gleichen Inputs für die gleiche deltaTime abarbeitet und in Form von Status-Updates (Position etc.) bestätigt. Der Client verwirft die gesammelten Inputs nicht sofort nach dem Senden, sondern behält diese noch etwas länger. Empfängt der Client nun vom Server ein Status-Update, dann steht dort drin neben der Position etc. auch welches das letzte vom Client abgearbeitete Input war (z.B. eine Id, oder die Netzwerkzeit). Da der letzte verarbeitete Input aufgrund des Lags in der Vergangenheit liegen muss, heisst das auch dass der Client in der zwischenzeit vielleicht 5 weitere Inputs gesammelt und verarbeitet hat. Also setzt man den Spieler nun an die vom Server gemeldete Position, aber arbeitet die 5 Inputs die zuvor schonmal abgearbeitet wurden noch einmal ausgehend von der Server-Position ab. Das heisst im Endeffekt: Der Server korrigiert den Client zwar, der Client versucht jedoch das Lag zu umgehen, indem er aufgrund der Inputs vorausrechnet wo er sich eigentlich befinden müsste, wenn er einen Ping von 0ms hätte. Falls es bei den Korrekturen zu kleinen Rucklern kommt, kann man sich auch die Abweichung merken und diese über die Zeit ausgleichen statt sofort (Interpolation). Die Lag Compensation findet hingegen auf dem Server statt. Diese dient dazu, dass Spieler exakt auf andere Spieler zielen können und nicht vorauszielen müssen. Es wird davon ausgegangen, dass alle nicht lokalen Spieler beim Client interpoliert werden (das heisst z.B. 100ms in der Vergangenheit dargestellt werden, dafür flüssig, ohne Ruckler). Der lokale Spieler befindet sich aufgrund der Client Prediction in der Gegenwart (vom Server aus gesehen, sogar in der Zukunft), während sich nicht lokale Spieler 100ms in der Vergangenheit befinden... Der Server speichert zu diesem Zweck für eine bestimmte Zeit lang alle Welt-Updates (Positionen aller Spieler in der Welt, Zeitpunkt etc.). Empfängt er nun von einem Client ein Input das verarbeitet werden soll, versetzt er zuerst alle anderen Spieler in die Vergangenheit zurück (sei es für Kollisionen oder Raycasts). Dafür muss man die Latenz des Clients kennen, sowie dessen verwendete Interpolationszeit für nicht lokale Spieler (z.B. 100ms). Man rechnet also die Input-Zeit minus die Latenz minus die Interpolationszeit. In diese Zeit versetzt man alle anderen Spieler zurück, indem man die zwei zwischengespeicherten Welt-Updates heraussucht die direkt vor dieser Zeit und danach liegen. Zwischen diesen beiden Updates werden die Positionen der anderen Spieler aufgrund der berechneten Zeit dann interpoliert. Sind alle anderen Spieler zurückversetzt wird nun das Input verarbeitet. Danach werden die anderen Spieler jedoch wieder an die ursprüngliche Position (Gegenwart) versetzt. Den lokalen Spieler lässt man wo er ist. Also schon sehr komplex das Ganze... Hier noch ein paar Unity-spezifische Tipps wie man die Server-Autorität mit der High Level API umsetzen kann: Es empfiehlt sich eine eigene Klasse zu erstellen die vom NetworkManager ableitet und einige Methoden überschreibt. Unity bietet die Möglichkeit von ClientRPCs (Server zu Client) und Commands (Client zu Server). Es ist natürlich verlockend die Client Inputs via Commands zu senden. Aus Gründen der Performance empfiehlt es sich jedoch eigene "Messages" zu erstellen, die von der Klasse MessageBase ableiten. Im eigenen NetworkManager kann man die Methode OnStartServer überschreiben und dort die Message registrieren mit: NetworkServer.RegisterHandler(...) Beim Client (z.B. innerhalb eines NetworkBehaviours) kann man die eigenen Messages dann senden via connectionToServer.Send(messageId, message) Ich hoffe das hilft dir etwas weiter
×
×
  • Create New...