2017-02-03 4 views
2

Ich habe mich seit Tagen über dieses Problem am Kopf kratzen, so dass jede Hilfe sehr geschätzt wird.Unity Multiplayer FPS-Client/Server-Interaktionsprobleme

Das Ziel: Ich habe eine einfache FPS für Lernzwecke, wo ein Spieler eine Waffe abfeuern kann. Ich möchte, dass die Kunden die Einschusslöcher sehen. Ich versuche dies zu erreichen, indem ich eine serverseitige Methode anrufe, wenn der Client versucht, die Waffe abzufeuern. Die serverseitige Methode sollte dann Raycast von der Spieler-Kamera und spawn ein Einschussloch für alle zu sehen.

Das Problem: Ich kann dies teilweise funktionieren, indem Sie den Player als Parameter an die Server-Methode übergeben. Da mein Raycasting jedoch auf der Basis der Player-Kamera erfolgen muss, erscheinen die Einschusslöcher auf der Zeichenhöhe (da der Player und nicht die Kamera verwendet wird)

Es wird mir nicht erlaubt, eine Kamera zu passieren durch. Ich habe auch versucht, ein leeres Spielobjekt mit dem Namen bullet spawn zu erstellen und es weiterzugeben, aber ich bekam einen "Objektverweis, der nicht auf die Instanz eines Objekts gesetzt wurde". Derselbe Fehler scheint für jedes Child-Element des Players aufzutreten, das ich an die serverseitige Methode übergeben möchte.

Ich bin mir nicht sicher über den richtigen Weg, dies zu erreichen .. Sorry für die beschissene Formatierung auf meinem Code. Ich hatte Schwierigkeiten, es hier einzufügen, und ich nahm Schnipsel, also entschuldige ich mich im Voraus.

Ich werde den entscheidenden Code schreiben:

void Update() 
     { 
       if (isLocalPlayer) 
       { 
     if (Input.GetButton("Fire1")) 
        { 
         CmdFire(BulletSpawn); 
        } 
     } 
[Command] 
    void CmdFire(GameObject Player) 
    { 
     Ray shooterRay = new Ray(Player.transform.position, Player.transform.forward); 
     if (Physics.Raycast(shooterRay, out Hit, 10000)) 
     { 
      Debug.Log("player hit"); 
      GameObject Bullet_Hole = (GameObject)Instantiate(BulletHole_Prefab, Hit.point, Quaternion.FromToRotation(Vector3.up, Hit.point)); 
      NetworkServer.Spawn(Bullet_Hole); 
     } 
    } 
+0

Dieser Abschnitt soll eigentlich sein, dies zum Beispiel Zwecken ... if (Input.GetButton („Fire1“)) { CmdFire (Spieler); } –

+0

Vermutlich synchronisieren Sie die Position der _gun_? Es wäre einfacher für Sie, den Strahl von der Spitze der Waffe zu senden, die der Spieler benutzt. Der Server hat natürlich keine Instanz, die die Kamera des Spielers darstellt, also würde man mit einer "Kamera" auf dem Server nichts erreichen. Sie müssten den Kameraansichtsvektor auf andere Weise an den Server übergeben. –

+0

Ab sofort synchronisiere ich nur die Rotation und Position des Players. Da die Waffe ein Kindobjekt des Spielers ist, sieht man auch, dass es sich um eine Bewegung handelt. Wenn man nach oben oder unten schaut, ist das natürlich nicht synchron. Das Problem mit dem Strahl von der Spitze der Waffe ist, wenn Ihre Waffe nicht gerade ist, wird Ihr Schuss nicht auf Ihrem Bildschirm zentriert sein. Ich werfe aus der Kamera, um sicherzustellen, dass die Kugel in die Mitte geht. Damit die Waffe so aussieht, als ob sie im Spiel gehalten wird, wird sie in einem Winkel und leicht nach rechts von der Mitte des Bildschirms erscheinen, wodurch sich die Einstellung leicht anfühlen würde. –

Antwort

0

Denk darüber auf diese Weise. Was ist es, dass du deine Waffe abfeuern musst? Sie benötigen den Schuss- und die Schussrichtung (in Ihrem einfachen Fall). Versuchen Sie also, nur diese Informationen weiterzugeben. Ihr CmdFire sollte wie void CmdFire aussehen (Vector3 firePoint, Vector3 fireDirection). Denken Sie daran, dass wenn Sie das Player-Spielobjekt übergeben, es serialisiert und an den Server gesendet wird, was viel unnötigen Netzwerkverkehr verursacht. Bleiben Sie bei Werttypen und einfachen Objekten für Befehle.

Dies hat mich letztendlich zur Lösung geführt. Danke für den Ratschlag. Ich habe einfach zwei Vector3-Parameter übergeben, wie Sie vorgeschlagen haben, die die Position und Richtung von Raycast darstellen. Ich kann jetzt sowohl vom Client als auch vom Server schießen und sehe die Einschusslöcher auf beiden. Hier ist der Code, der es bei fest jemand in dieser läuft später:

void Update() 
    { 
     if (isLocalPlayer) 
     { 
      if (Input.GetButton("Fire1")) 
      { 
       Vector3 FiringSpot = new Vector3(PlayerCam.transform.position.x, PlayerCam.transform.position.y, PlayerCam.transform.position.z); 
       Vector3 FireDirection = PlayerCam.transform.forward; 
       CmdFire(FiringSpot, FireDirection); 
      } 

    [Command] 
    void CmdFire(Vector3 firingPoint, Vector3 FiringDirection) 
    { 
     Ray shooterRay = new Ray(firingPoint, FiringDirection); 
     if (Physics.Raycast(shooterRay, out Hit, 10000)) 
     { 
      GameObject Bullet_Hole = (GameObject)Instantiate(bullet_Hole_Prefab, Hit.point, Quaternion.FromToRotation(Vector3.up, Hit.point)); 
      NetworkServer.Spawn(Bullet_Hole); 
      Destroy(Bullet_Hole, 10); 
     } 
    } 
+0

FYI für alle, die das verwenden möchten .... Ich habe gerade bemerkt, dass eine schließende Klammer für die Aktualisierte Methode fehlt. Das ist nur ein Kopier-/Einfügefehler. –

Verwandte Themen