Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

SyncVars are unreliable?

Discussion in 'Multiplayer' started by voltage, May 21, 2016.

  1. voltage

    voltage

    Joined:
    Nov 11, 2011
    Posts:
    515
    I've been messing with SyncVars and they're not adding up. Either I discovered a bug or I'm terribly misguided on how this works.

    From my understanding, when the Server sees an update to a SyncVar, it will automatically update to all the Clients. So I tested this;
    Code (CSharp):
    1. [SyncVar] public int test;
    2.  
    3. Void Update()
    4. {
    5.      if (isServer)
    6.      {
    7.           test = 1;
    8.           Debug.Log("Test is " + test);
    9.      }
    10.  
    11.      if (!isServer)
    12.      {
    13.           Debug.Log("Test is " + test);
    14.      }
    15. }

    Both Server and Remote Client claim test = 1. The SyncVar is a success.

    So then I try it with a Cmd;
    Code (CSharp):
    1. [SyncVar] public int test;
    2.  
    3. public override void OnStartLocalPlayer()
    4. {
    5.      if (!isServer)
    6.      {
    7.           CmdTest();
    8.      }
    9.      base.OnStartLocalPlayer();
    10. }
    11.  
    12. [Command]
    13. void CmdTest()
    14. {
    15.      test = 1;
    16. }
    17.  
    18. Void Update()
    19. {
    20.      if (isServer)
    21.      {
    22.           //test = 1;
    23.           Debug.Log("Test is " + test);
    24.      }
    25.  
    26.      if (!isServer)
    27.      {
    28.           //Debug.Log("Test is " + test);
    29.      }
    30. }

    Here are the Results;

    All of a sudden once I update the SyncVar through a Cmd, Test is continually updating as both Zero and One. I know I've got to be missing something.
     

    Attached Files:

  2. voltage

    voltage

    Joined:
    Nov 11, 2011
    Posts:
    515
    I've been trying things for a while and I thought I came up with the answer once, but I found holes in my argument. My only guess is that there might be a case where the Server and the Remote Client get the Update to SyncVar 'test', but the Server's Local Client doesn't. Which seems strange. Aren't they connected? Somehow, someway, test is able to be both 0 and 1 at the same time.

    That shouldn't be the case though, considering an Update to the Var is SUPPOSED to change it across the entire Network. I even tried other code like Instantiate, 0 & 1 are both acceptable answers apparently.
     
  3. Oshroth

    Oshroth

    Joined:
    Apr 28, 2014
    Posts:
    99
    Its really hard to tell whats happening in the log because of the Collapsed log. I can't see anything wrong with the code. Server's local client is the same instance as the server so they must be the same value.
     
  4. JirinCrawford

    JirinCrawford

    Joined:
    May 2, 2016
    Posts:
    5
    I'm going to guess that you're running the server as a Host, and the script with the test SyncVar is attached to the prefab you've registered as the player object. If that's the case, I think you just have two objects spawned. What I think is happening:

    1. The server starts hosting the game. It spawns a player object for itself, A.
    2. A.OnStartLocalPlayer runs on the server. Since this is running on the server A.isServer is true, so A.CmdTest() isn't called. A.test is 0.
    3. The remote client connects to the game. The server spawns a player object for it, B.
    4. B.OnStartLocalPlayer runs on the remote client. B.isServer is false because we're running on a client, so it calls B.CmdTest() on the server.
    5. B.CmdTest() runs on the server, setting B.test to 1.
    6. The server runs A.Update and B.Update, reporting 0 and 1. (The remote client also runs A.Update and B.Update, but because isServer is false over there, it doesn't print anything).

    Could this be the problem?
     
  5. voltage

    voltage

    Joined:
    Nov 11, 2011
    Posts:
    515
    This helped a ton Jirin. I was overlooking the possibility of the SyncVar only updating the variable associated with the PlayerObject that initially called the Command. Based on how the Docs explained it, I assumed the same Var would equal the same across the entire network. I put it to the test and it works!