Search Unity

SyncVar Not Working

Discussion in 'Multiplayer' started by DRRosen3, Jul 6, 2015.

  1. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    Trying to figure out why my variables aren't syncing from the server to the client. I've watched them change on the server...but they're not changing on the client.

    Code (CSharp):
    1. usingUnityEngine;
    2. usingUnityEngine.Networking;
    3. usingSystem.Collections;
    4.  
    5. public class Input : NetworkBehaviour
    6. {
    7.     private bool cameraOn;
    8.     private Player player;
    9.  
    10.     void Awake()
    11.     {
    12.        player = GetComponent<Player>();
    13.     }
    14.  
    15.     void Update()
    16.     {
    17.         if(!isLocalPlayer)
    18.             return;
    19.  
    20.         if(!cameraOn)
    21.         {
    22.             Camera.main.SendMessage("SetTarget", transform);
    23.             cameraOn = true;
    24.         }
    25.  
    26.         if(Input.GetKeyDown(KeyCode.Q))
    27.             player.CmdLastMove();                
    28.  
    29.         if(Input.GetKeyDown(KeyCode.E))
    30.             player.CmdNextMove();
    31.     }
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Networking;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. public class Player : NetworkBehaviour
    7. {
    8.     public List<Move> LearnedMoves = new List<Move>(), KnownMoves;
    9.     [SyncVar(hook="SelectMove")]
    10.     public int activeMoveIndex;
    11.     public Move activeMove;
    12.  
    13.     [Command]
    14.     public void CmdNextMove()
    15.     {
    16.         if(activeMoveIndex == KnownMoves.Count - 1)
    17.         {
    18.             activeMoveIndex = 0;
    19.         }
    20.         else
    21.         {
    22.             activeMoveIndex++;
    23.         }
    24.         activeMove = KnownMoves[activeMoveIndex];
    25.     }
    26.     [Command]
    27.     public void CmdLastMove()
    28.     {
    29.         if(activeMoveIndex == 0)
    30.         {
    31.             activeMoveIndex = KnownMoves.Count - 1;
    32.         }
    33.         else
    34.         {
    35.             activeMoveIndex--;
    36.         }
    37.         activeMove = KnownMoves[activeMoveIndex];
    38.     }
    39.  
    40.     public void SelectMove(int _activeMoveIndex)
    41.     {
    42.         activeMoveIndex = _activeMoveIndex;
    43.         activeMove = KnownMoves[activeMoveIndex]
    44.     }
     
    Last edited: Jul 6, 2015
  2. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    BUMP ... A more detailed explination: If I run the host inside Unity and the client in the application... In the client if I press Q or E I can see that in the inspector inside Unity (the host) the variables are changing. So the commands are indeed being sent to the host/server. If I then run the client inside Unity and the host in the application... In the client (which is now Unity) if I press Q or E I see that the variables are not changing in the inspector. So the SyncVars aren't actually syncing from the server to the client. The GameObject has the following attached to it, in this order:
    Transform
    Capsule Collider
    Rigidbody
    Animator
    Network Identity (Local Player Authority)
    Network Animator
    Player (Custom Script)
    Input (Custom Script)
    Attack One (Custom Script)
    Attack Two (Custom Script)
    Network Transform
     
  3. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
  4. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    If the value is changing on the server, but not synchronizing on the client my best guess is that maybe it's not setting dirty bit properly. You can troubleshoot this 2 ways. either...
    -Strip code down to bar bones (without network animator, network transform, etc). I know those additional components had some bugs affecting syncVars. Just have your Network Identiy and NetworkBehavior script, nothing else. See if this resolves issue.
    -Manually SetDirtyBit( ) to see if it synchronizes to client.

    Just some things to try.
     
  5. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
    it looks like it should work. You could put a Debug.LogError() in your SelectMove() function to check if it is really being called.. or try a debugger.

    1. public void SelectMove(int _activeMoveIndex)
    2. {
    3. Debug.LogError("SelectMove for " + netId + " index:" + _activeMoveIndex);

    4. activeMoveIndex = _activeMoveIndex;
    5. activeMove = KnownMoves[activeMoveIndex]
    6. }
     
  6. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,913
    Similar issue here. Am I not getting how SyncVars are supposed to work? Why can't I use "buildProgress" instead of the "value" in the OnBuildProgressChanged function?

    buildProgress is remaining what it was when joining. The slider value in the hook function will only match the "value" sent, but won't read the server's "buildProgress".

    The SyncVar is not being read by the clients.

    Edit: I think this is the issue - http://issuetracker.unity3d.com/issues/syncvar-hooks-on-host-dont-have-access-to-old-value

    http://forum.unity3d.com/threads/ne...s-dont-match-expectation.334890/#post-2196522

    http://forum.unity3d.com/threads/syncvar-hook-function-question.341374/#post-2208714

    Member variable values won't update unless you apply them in the hook function, so you just have to apply it manually.
     
    Last edited: Aug 20, 2015
  7. Disastorm

    Disastorm

    Joined:
    Jun 16, 2013
    Posts:
    132
    I believe the issue is due to your local player authority.
    I believe it said somewhere in some docs that this is what determines which direction the SyncVar goes.
    If its Local Player Authority it goes from Player -> Server
    otherwise its Server -> Player

    In case you are wondering, I believe most of the HLAPI components act in the same way such as NetworkTransform, etc.
     
    nikolan00 likes this.
  8. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
    SyncVar hooks functions are passed the new value of the variable, and it is up to your code to apply that value to the local member variable.

    Code (CSharp):
    1. void OnBuildProgressChanged(float value)
    2. {
    3.    Debug.Log("diff = " + (value -buildProgress));
    4.    buildProgress = value;
    5. }
    This allows your code to calculate the difference between the old and new values.
     
    MrLucid72 and Enigma_Syrus like this.
  9. Enigma_Syrus

    Enigma_Syrus

    Joined:
    Aug 1, 2015
    Posts:
    1
    I... just found this now... and I thank you... I have been setting it in all sorts of squirly ways...
     
  10. U-GeeN

    U-GeeN

    Joined:
    Mar 22, 2015
    Posts:
    95
    Hi, I have same issue. The SyncVar from Host isn't synching to other client.
    And the SyncVar Attribute is not shown in the inspector. What does that mean?
     
  11. dukotron

    dukotron

    Joined:
    Jul 26, 2013
    Posts:
    5
    I have a similar issue, my client doesn't get the updated variables no matter what I do, I tried every possible variation that exists, I even tried to send them as messages using _client.send and then replying with the server and assigning it to another local variable but no matter what magic I use the variable always displays it's content in the inspector but if i try to use it on a client side function it's empty. I have even posted on 3 different sites my code between the 50th and 100th attempt but 0 response. After like 60 hours I'm wondering if I'm retarded or is this completely broken...
     
  12. U-GeeN

    U-GeeN

    Joined:
    Mar 22, 2015
    Posts:
    95
    It could be a bug, so I try to write another script to reproduce it.
    Because Syncvar in other scripts works fine.
     
  13. U-GeeN

    U-GeeN

    Joined:
    Mar 22, 2015
    Posts:
    95
    Another questions: what will the behaviour of a SyncVar be if no authority on NetworkIdentity is checked?
    Will it still be synched or do I have to do it manually via hook?
    Does an Object with "Server Only" option execute Client functions?
    And does a SyncVar needs to be public?
     
  14. windwolfx_23

    windwolfx_23

    Joined:
    Jan 15, 2015
    Posts:
    11
    so if no hook function is used it will sync automatically, but if hook function is used you have to manually set the variable to the value passed by hook function. I wish I saw this post earlier....I'v been looking for solution for days!