Jump to content
Unity Insider Forum

Input Synchronisieren? (für Noobs ^^)


AniProGuy2

Recommended Posts

Hallo Unity Community,

 

bevor ich meine Frage hier stelle, möchte ich eine kleine Bemerkung machen. Und zwar versuche ich mich in Unity Networking einzuarbeiten und stehe dabei noch recht am Anfang. Es ist auch das erste mal, dass ich mich mit sowas befasse und daher bitte ich darum, es mir nachzusehen, wenn ich (vielleicht auch hiermit) dumme Fragen stelle. Ich habe jetzt schon über eine Stunde im Internet gesucht und bin leider nicht wirklich fündig geworden, weshalb ich auch diese Frage hier überhaupt erst in Betracht gezogen habe.

 

Und zwar habe ich bisher für jeden Spieler einen Avatar (einfach ein Cube), der gespawnt wird und den er dann bewegen kann. Die Bewegung zu synchronisieren ist ja einfach und dort gibt es auch keine Probleme aber ich frage mich, wie ich z.B. das drücken einer Taste synchronisieren kann?

 

Angenommen z.B. jeder Cube hat ein Script, das ihn beim Klicken der Taste "T" eine Kugel spawnen lässt. Ich könnte jetzt das Klicken der Taste bei meinem Cube abfragen (und das Script bei den Cubes bei allen anderen Spielern deaktivieren) und dann einfach via Network.Instantiate die Kugel überall spawnen lassen. Aber diese Methode erscheint mir im generell irgendwie unlogisch, denn dann würde ich viel mehr Daten senden. Ich würde allgemein gesagt mit dieser Methode doch immer die Aktion (die auf einen Input folgt) synchronisieren. Dann müsste ich ja auch, wenn ich auf Tastendruck eine Animation abspielen will, meinem Cube bei allen anderen Spielern mitteilen, dass er sie abspielen soll.

 

Meine Idee war es, das Klicken der Taste von meinem Spieler aus an alle anderen zu senden. Dann würden dort die Scripte auf meinem Cube einfach via Instantiate die Kugel spawnen. Mit dieser Methode würde man (im Allgemeinen) nur das Drücken von Tasten synchronisieren und bei jedem Spieler die damit verbunden Aktionen im Script selbst bestimmen lassen. Das Spiel wäre somit ja auch Synchron, weil Scripte bei jedem Spieler die selben "Entscheidungen treffen" würden.

 

Meine Fragen sind nun: ist das sinnvoll (wenn nicht, dann erklärt mir bitte warum)? Und vor allem, wie kann ich das machen?

 

Ich bedanke mich schonmal im Vorraus für jede Antwort!

 

MfG,

AniProGuy2

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wenn du es so machst, dass du via Instantiate bei jedem Spieler lokal dann die Kugel spawnen lassen möchtest, dann hast du aber das Problem, dass die Kugel selbst nicht mehr mit dem Netoworksystem von Unity synchronisiert ist. Network.Instantiate macht da schon mehr sinn, weil du dann auch mehr Fehlerquellen ausschließt und du Unity einfach das Synchronisieren überlasst.

Wenn du aber einfach den Tastendruck synchronisieren willst, dann benutze doch einfach die [RPC] Attribute bei deinen Methoden. Diese wird dann bei jedem Spieler aufgerufen.

 

Allgemein rate ich dir aber die HLAPI von Unity zu benutzen und nicht die LLAPI.

Dort sind einige Dinge einfacher zu lösen. ich weiß auch gar nicht wie lange die LLAPI in Unity überhaupt noch unterstützt wird.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also ich arbeite bereits mit der HLAPI, soweit ich weiß. Also ich genauergesasgt habe ich bis jetzt nach einem Tutorial gearbeitet, dass knapp ein Jahr alt ist (

). Ich gehe davon aus, dass du das meinst, oder?

 

Könntest du mir bitte genauer erklären, wie ich [RPC] Attribute verwenden muss, um die Tasten zu synchronisieren? Das wäre sehr nett.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Oh Moment ich habe grade LLAPI mit was anderem Verwechselt :D

 

Also soweit ich weiß wird [RPC] gar nicht mehr benutzt. Bei dem Neuen Networksystem musst du mit ClientRpc und Command Attributen arbeiten. Erstelle einfach eine Methode die ein [Command] als Attribut stehen hat. Diese rufst du bei dem Tastendruck auf. Damit wird nun wenn du die Methode aufrufst, die Methode nicht bei dir aufgerufen sondern bei dem Host. In dieser Methode kannst du nun eine weitere Methode aufrufen die [ClientRpc] als Attribut bestitzt. Somit ruft der Host aus der Command Methode die ClientRpc Methode bei allen Clients aus.

 

Das Heißt:

Tastendruch -> Wird an Host gesendet -> Host sendet an alle Clients.

 

Beispiel:

 

void Update()
{
  if(Input.GetKeyDown(KeyCode.A))
  {
		 CmdKeyDown();
  }
}

[Command]
void CmdKeyDown()
{
  RpcKeyDown();
}
[ClientRpc]
void RpcKeyDown()
{
   Mache was...
}

 

Wichtig ist, dass die Namen der Command Methoden mit Cmd beginnen und die Namen der ClientRpc Methoden mit Rpc beginnen.

 

Wichtig ist: Du kannst nie von einem Client direkt an alle Clients senden. Also von einem Client aus kannst du keine ClientRpc Methode aufrufen. Die Daten werden Immer über den Host ausgetauscht.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,

 

Ich habe noch eine andere Frage. Und zwar versuche ich gerade, jeden Spieler beim Spawnen als Client oder Host einzuordnen. Jenachdem, was er ist, wird ein Parent zu einem Empty gesetzt, das entweder alle Clienten oder den Host als Children hat.

 

Mein Code ist folgender:

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class SetupLocalPlayer : NetworkBehaviour {
public SceneSettings settings;
void Start () {
 settings = GameObject.Find ("NetworkManager").GetComponentInChildren<SceneSettings> ();
 // set as host or client
 if (isServer) {
  transform.SetParent (GameObject.Find ("NetworkManager").transform.FindChild ("Players").transform.FindChild ("Host").transform);
 }

 if (isClient) {
  transform.SetParent (GameObject.Find ("NetworkManager").transform.FindChild ("Players").transform.FindChild ("Clients").transform);
 }
}
}

 

Nur leider funktioniert das nicht richtig. Und zwar wird setzt nun jeder Spieler einen Parent zum "Client"-Empty (da scheinbar beide Abfragen wahr sind). Mit Network.isClient bzw. Network.IsServer funktioniert es leider auch nicht. Weiß du, woran das liegt?

 

MfG,

AniProGuy2

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ersteinmal würde ich dir einen kleinen Tipp geben: Benutzte so wenig wie du kannst diese GameObject.Find() sowie transform.FindChild() Methoden. Diese sind bei einer größeren Anzahl von Objekten ziemlich Rechenaufwendig. Übergebe die beiden GameObjects Clients und Host als Variable im Inspector. Das ist sauberer und schneller.

 

Benutze niemals wenn du das neue Networksystem von Unity benutzt die Klasse "Network". Diese gehört noch zu dem alten Networksystem. Wir arbeiten aber hier mit dem neuen.

 

Probiere mal diese Abfrage:

if(NetworkServer.isActive)
{
   // Host
}
else
{
   // Client
}

 

So müsste es gehen

Link zu diesem Kommentar
Auf anderen Seiten teilen

Kleine Korrektur:

 

NetworkServer.active ist nicht dazu da, um zu gucken, ob man host ist. Das ist eher dazu gedacht, ob ein Spiel erfolgreich gehostet wurde. Also quasi wenn man Listen() oder sowas benutzt.

 

NetworkServer.active gibt auch true, wenn man host ist, aber nicht wenn man gespawned ist. Das kann je nachdem Probleme geben.

 

Richtig ist isServer vor allem, wenn es um GameObjects mit NetworkIdentify geht.

 

Folgende gibt es:

  • isServer
  • isClient
  • isLocalPlayer

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...