Verwendung von Command und RpcClient

7

Ich arbeite an einem rundenbasierten Multiplayer-Projekt in Unity 5.4 und Unity Networking. Ich versuche, Networking zu lernen, und ich frage mich, wann ich [Command]und verwenden soll [RpcClient].

Ich kenne den Unterschied zwischen beiden:

  • Command werden vom Server ausgeführt und der Client wird mit ihm synchronisiert (IE: Spieler X hat eine Kugel abgefeuert, den Befehl an den Server gesendet, die Flugbahn berechnet und mit den Clients synchronisiert).
  • RpcClient Werden Befehle an den Client gesendet (IE Player ist gestorben?)

Welche Frage muss ich mir beim Schreiben einer Funktion stellen, um festzustellen, ob es sich um einen Befehl oder einen Remoteprozeduraufruf handelt?

PL Audet
quelle
Übrigens: Verwenden Sie diese Option, Commandwenn es sich um eine Clientaktion handelt, für die eine Antwort vom Server erforderlich ist, z. B. das Senden einer GET\POSThttp-Anforderung und das Erwarten eines Ergebnisses. Verwenden RpcClientSie 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 einer PUThttp-Anforderung.
Giora Guttsait
1
Frage: Muss ich den Server auf das aktualisieren, was ein Client getan hat? Befehl. Muss ich einen Client aufgrund eines Ereignisses auf dem Server aktualisieren? RPC
jgallant
Ich glaube nicht, dass es eine universelle Frage geben kann. Wenn Sie ein bisschen üben, werden Sie leicht herausfinden, was die Methode bewirkt: Lassen Sie andere wissen oder hören Sie zu, was andere getan haben
Jewhen

Antworten:

5

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 NetworkTransformsnicht 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, NetworkTransformusw.) 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 NetworkConnectionObjekt, 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 ShotObjectBefehl, 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 FireGunBefehl 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.

Coburn
quelle
Für zukünftige Benutzer: Einfach anders ist [Befehl] [1]: Client zu Server [RPC] [2]: Server zu Client [1]: docs.unity3d.com/ScriptReference/… [2]: docs.unity3d.com/ Manual / UNetActions.html
Muhammad Faizan Khan