2017-06-30 8 views
0

Ich versuche, SyncVar zu verwenden, aber ich verstehe nicht ganz, was ich falsch mache, wenn ich es falsch mache, dass ist. Hier ist die Situation:UNET SyncVar auf Serverseite nicht aktualisiert

1) Ich habe zwei öffentliche SyncVar suchen: redFunds und blueFunds und zwei lokale „alte“ -Ausführung mit vergleichen

2) Ich habe die SyncVar unter Start initiieren, indem Cmd_UpdateXxx verwenden, das funktioniert

3) ich habe zwei Tasten, eine für jede SyncVar

4) aktualisiere ich die SyncVar gegen den oldXxxFunds vergleichen. Wenn ich einen Treffer habe, zeige ich in Szene

Wenn ich den Code ausführen, zeigt es die richtigen Zahlen auf der Szene auf beiden Playern (Rot & Blau), aber das ist nicht vollständig im Editor beim Betrachten der "öffentlichen" SyncVar's wider . Wenn man den roten Knopf drückt, wird im Editor nur der rote Spieler und nicht der blaue Spieler angezeigt.

Kann mir jemand erklären, was ich hier falsch mache? ... wenn ich etwas falsch mache, ist das. Sollte ich die Änderungen nicht auch im Editor sehen?

[SyncVar] public int redFunds; 
[SyncVar] public int blueFunds; 
public int oldRedFunds; 
public int oldBlueFunds; 



void Start() { 

if (!isLocalPlayer) 
     return; 
Cmd_UpdateRed (10); 
Cmd_UpdateBlue (20); 

} 


// Button 
void btn_Red() { 
if (!hasAuthority) 
     return; 
Cmd_UpdateRed (10000); 
} 

void btn_Blue() { 
if (!hasAuthority) 
     return; 
Cmd_UpdateBlue (20000); 
} 

[Command] 
void Cmd_UpdateRed (int _value) { 
redFunds = _value; 
} 

[Command] 
void Cmd_UpdateBlue (int _value) { 
blueFunds = _value; 
} 

void Update() { 

if (redFunds != oldRedFunds) { 

    txt_RedTotalFunds = GameObject.Find ("txt_RedTotalFunds").GetComponent<Text>(); 
    txt_RedTotalFunds.text = "$" + redFunds; 
    oldRedFunds = redFunds; 
} 

if (blueFunds != oldBlueFunds) { 

    txt_BlueTotalFunds = GameObject.Find ("txt_BlueTotalFunds").GetComponent<Text>(); 
    txt_BlueTotalFunds.text = "$" + blueFunds; 
    oldBlueFunds = blueFunds; 
} 

} 
+0

Wie viele Objekte mit diesem Skript existieren und wer sind die Eigentümer? – Fenixrw

+0

@Fenixrw es ist vier Objekte, die Spieler, in denen dieser Code liegt. – PeterK

+0

Ich werde hier einige Tests durchführen, um zu sehen, ob ich das Problem finden kann. – Fenixrw

Antwort

1

Der beste Weg, ich kann denken, ist eine GameRoomInfo als Netzwerk-Objekt im Besitz des Servers zu verwenden.

Es kann mit zwei einfachen Skripten wie folgt vorgenommen werden:

GameRoomInfo Script

using UnityEngine; 
using UnityEngine.Networking; 
using UnityEngine.UI; 
using System.Collections; 

public class GameRoomInfo : NetworkBehaviour 
{ 

    public Text txt_RedTotalFunds; 
    public Text txt_BlueTotalFunds; 


    public int oldRedFunds = 0; 
    public int oldBlueFunds = 0; 

    [SyncVar] 
    public int redFunds; 
    [SyncVar] 
    public int blueFunds; 

    // Use this for initialization 
    void Start() { 

    } 

    void Update() 
    { 

     if (redFunds != oldRedFunds) 
     { 

      //txt_RedTotalFunds = GameObject.Find("txt_RedTotalFunds").GetComponent<Text>(); 
      txt_RedTotalFunds.text = "$" + redFunds; 
      Debug.Log("Red - $" + redFunds); 
      oldRedFunds = redFunds; 
     } 

     if (blueFunds != oldBlueFunds) 
     { 

      //txt_BlueTotalFunds = GameObject.Find("txt_BlueTotalFunds").GetComponent<Text>(); 
      txt_BlueTotalFunds.text = "$" + blueFunds; 
      Debug.Log("Blue - $" + blueFunds); 
      oldBlueFunds = blueFunds; 
     } 

    } 
} 

Spieler Script

using UnityEngine; 
using UnityEngine.Networking; 
using UnityEngine.UI; 
using System.Collections; 

public class Player : NetworkBehaviour { 

    [System.Serializable] 
    public enum PlayerColor { Red, Blue}; 

    [SyncVar] 
    PlayerColor playerColor;//used to update the right variables (Blue player updates blueFunds and Red player updates redFunds) 

    static int colorSelect = 0; 

    void Start() 
    { 
     if(isServer) // the server selects the player color when created 
     { 
      switch(colorSelect % 2) 
      { 
       case 0: 
        playerColor = PlayerColor.Red; 
        break; 
       case 1: 
        playerColor = PlayerColor.Blue; 
        break; 
      } 

      colorSelect++; 
     } 
    } 

    void Update() 
    { 
     if (!isLocalPlayer) 
      return; 

     if (hasAuthority && Input.GetKeyDown(KeyCode.KeypadPlus)) 
     { 
      Cmd_UpdateAdd(10); 
     } 

    } 

    // Button 
    void btn_Update() 
    { 
     if (!hasAuthority) 
      return; 
     Cmd_Update(0); 
    } 

    void btn_Add() 
    { 
     if (!hasAuthority) 
      return; 
     Cmd_Update(10); 
    } 


    [Command] 
    public void Cmd_Update(int _value)//The command updates the GameRoomInfo variables according to the player color 
    { 
     switch (playerColor) 
     { 
      case PlayerColor.Red: 
       FindObjectOfType<GameRoomInfo>().redFunds = _value; 
       break; 
      case PlayerColor.Blue: 
       FindObjectOfType<GameRoomInfo>().blueFunds = _value; 
       break; 
      default: 
       break; 
     } 
    } 

    [Command] 
    public void Cmd_UpdateAdd(int _value) 
    { 
     switch (playerColor) 
     { 
      case PlayerColor.Red: 
       FindObjectOfType<GameRoomInfo>().redFunds += _value; 
       break; 
      case PlayerColor.Blue: 
       FindObjectOfType<GameRoomInfo>().blueFunds += _value; 
       break; 
      default: 
       break; 
     } 
    } 

} 

Ich habe einige kleine Änderungen vorgenommen Tests zu helfen. Fühlen Sie sich frei, sich Ihren Bedürfnissen anzupassen.

+0

Dank @Fenixrw habe ich endlich das Problem gelöst, mit dem ich seit ein paar Monaten gearbeitet habe. Die Lösung laut Fenixrw: "Die roten und blauen Fondsvariablen sind in jedem Spieler einzigartig. Wenn Sie also die roten Fonds im roten Spieler aktualisieren, wird dieser im blauen Spieler nicht aktualisiert." Du bist mein Held, ein GROSSER DANK :-) – PeterK

Verwandte Themen