0

I am trying to use SyncVar but I do not fully understand what I am doing wrong, if I do it wrong that is. Here is the situation:

  1. I have two public SyncVar's: redFunds and blueFunds and two local "old"-version to compare with

  2. I initiate the SyncVar in Start by using Cmd_UpdateXxx, that works

  3. I have two buttons, one for each SyncVar

  4. In Update I compare the SyncVar vs. the oldXxxFunds. If a hit I display on scene

When I run the code it does display the correct numbers on the scen on both players (Red & Blue) but that is not fully reflected in the editor when looking at the "public" SyncVar's. When pressing the red button it only reflect, in the editor, on the red player not the Blue.

Can someone explain to me what i am doing wrong here? ...if I am doing something wrong that is. Shouldn't I see the changes in the editor as well?

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

private 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;
    }
}
derHugo
  • 83,094
  • 9
  • 75
  • 115
PeterK
  • 4,243
  • 4
  • 44
  • 74
  • How many objects with that script exist and who are the owners? – Magrones Jul 01 '17 at 22:45
  • @Fenixrw it is four objects, the players where this code resides. – PeterK Jul 01 '17 at 23:55
  • I will do some testing here to see if I can find the problem. – Magrones Jul 02 '17 at 02:30
  • I think I understand the problem. The red and blue funds variables are unique in each player, so if you update the red funds in the red player, it will not be updated in the blue player. I don't know if it is possible with syncvars (should be), but you could use those variables as static, so they belong to the class and not to the object. Other way would be to use an object owned by the server to store this information. You can create a GameRoomInfo NetworkBehavior to store game room data. – Magrones Jul 02 '17 at 02:40
  • Tried to create a static SyncVar... does not work. The GameRoomInfo solution might be the best approach. – Magrones Jul 02 '17 at 02:52
  • Peter, did the GameRoomInfo approach fixed the problem? – Magrones Jul 04 '17 at 14:21
  • I just tested your structure and it worked :-) – PeterK Jul 04 '17 at 18:12
  • Glad I could help :-) – Magrones Jul 04 '17 at 18:30

1 Answers1

1

The best way I can think is to use a GameRoomInfo as an network object owned by the server.

It can be done with 2 simple scripts as follows:

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;

    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;
        }
    }
}

Player Script

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

public class Player : NetworkBehaviour 
{
    public enum PlayerColor
    { 
        Red, 
        Blue
    };

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

    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;
        }
    }
}

I have made some small changes to help testing. Feel free to adapt to your needs.

derHugo
  • 83,094
  • 9
  • 75
  • 115
Magrones
  • 413
  • 2
  • 9
  • Thanks to @Fenixrw i finally solved the problem I have worked with for a few month. The solution, as stated by Fenixrw: "The red and blue funds variables are unique in each player, so if you update the red funds in the red player, it will not be updated in the blue player.". You are my hero, a BIG THANKS :-) – PeterK Jul 04 '17 at 18:13