Hintergrund
Bei normalen Client-Server-Spielen ist der Server maßgeblich, dh er hat das letzte Wort darüber, wie der Spielstatus vorliegt, und ist dafür verantwortlich, dass die Clients den aktuellen Spielstatus kennen. Dazu wird die gesamte Spielelogik übernommen und anstelle der Clients * ausgeführt. Anschließend werden nach eigenem Ermessen Aktualisierungen gesendet. Die Grundbausteine dieser Mechanik sind die [Command]
, [ClientRpc]
und [TargetRpc]
Attribute. Diese sind nicht so hoch wie die automatische Synchronisierung [SyncVar]
und auch NetworkTransforms
nicht so niedrig wie Sockets.
* Dies geschieht so weit wie möglich, um nicht zu viel Netzwerkbandbreite (was zu einer schlechten Leistung führt) und Komplexität einzuführen. Normalerweise ist der Client für die Simulation und Vorhersage von Physik, Beleuchtung und anderen intensiven Aufgaben verantwortlich, während der Server nur den Objektstatus und die Positionen synchronisiert und Spielbenachrichtigungen zum Abspielen clientseitiger Sounds und zum Ändern der Benutzeroberfläche bereitstellt.
Wie sie sich unterscheiden
[ Befehl ] - Das [Command]
Attribut wird von einem Client (!) Aufgerufen und vom Server für dasselbe Objekt ausgeführt. Der Client kann dies nur für Objekte aufrufen, für die er die Berechtigung hat. Diese geben normalerweise eine Art Kundenabsicht weiter, wie das Abfeuern meiner Waffe oder das Senden einer Chat-Nachricht. Alle die automatische Synchronisierung zu ignorieren ( SyncVars
, NetworkTransform
usw.) ist dies die einzige Möglichkeit für den Kunden etwas auf dem Server und als solche alle Client - Netzwerk - Aktionen zu tun , die die Möglichkeit haben , müssen Sie das Spiel beeinflussen oder andere Clients zu ändern , eine sein , [Command]
dass der Kunde kann anrufen, um auf dem Server ausgeführt zu werden.
[ ClientRpc ] - Das [ClientRpc]
Attribut wird auf dem Server aufgerufen und auf allen Clients ausgeführt, die derzeit für ein bestimmtes Objekt mit dem Server verbunden sind. [ClientRpc]
wird am häufigsten verwendet, um die Kunden über Spieländerungen wie eine Änderung der Punktzahl oder über ihren Tod zu informieren (um Sound- und Todesanimationen auf den Bildschirmen aller Spieler abzuspielen).
[ TargetRpc ] - In Unity 5.4 hinzugefügt - Das [TargetRpc]
Attribut ist das gleiche wie oben, wird jedoch nur auf einem bestimmten Client ausgeführt, wenn es auf dem Server aufgerufen wird. Der Server übergibt ein NetworkConnection
Objekt, um anzugeben, welchen Client er ausführen möchte TargetRpc
.
Eine super hilfreiche Übersicht über all dies (einschließlich eines raffinierten Diagramms) finden Sie in der UNET-Tutorialserie .
Wenn die Serverautorität wichtig ist
Was ich oben beschrieben habe, ist die häufigste Verwendung für diese Art von Befehlen, bei denen die Serverautorität sehr wichtig ist (wie bei Wettbewerbsspielen). Gelegenheitsspiele, bei denen Betrug keine große Rolle spielt (Coop-Spiele, Spiele, bei denen Sie darauf vertrauen, dass die anderen Spieler nicht schummeln), sind möglicherweise anders strukturiert.
Ein Beispiel könnte ein Spiel sein, bei dem Sie eine Waffe abfeuern, um einen Feind zu erschießen. In einem nicht wettbewerbsorientierten Spiel, in dem Betrug kein Problem darstellt, habe ich möglicherweise einen ShotObject
Befehl, den Clients mit den von ihnen geschossenen Objekten aufrufen. Dies ist wirklich leicht zu betrügen, aber von geringer Komplexität. In einem wettbewerbsfähigen Multiplayer-Spiel würde ich jedoch einen FireGun
Befehl benötigen , der keine Argumente akzeptiert und den Raycast für den Schuss allein auf dem Server simuliert, damit Clients nicht schummeln können. Dies führt zu der zusätzlichen Komplexität des Sicherns der Serversimulation, wenn der Client schießt, den Raycast ausführt und dann mit dem Spiel fortfährt.
Die Grundregel lautet hier: Wenn die Serverautorität wichtig ist, führen Sie so viel wie möglich auf dem Server aus. Wenn dies nicht der Fall ist, können Sie tun, was Sie wollen.
Command
wenn es sich um eine Clientaktion handelt, für die eine Antwort vom Server erforderlich ist, z. B. das Senden einerGET\POST
http-Anforderung und das Erwarten eines Ergebnisses. VerwendenRpcClient
Sie diese Option, wenn es sich um ein Ereignis handelt, das aufgrund der Aktualisierungsschleife oder was auch immer auf dem Server auftritt. und die Clients müssen geändert werden, ähnlich wie bei einerPUT
http-Anforderung.