Search Unity

[Suggestion] SyncVar rules

Discussion in 'Multiplayer' started by DWORD, Jul 31, 2015.

  1. DWORD

    DWORD

    Joined:
    Jun 22, 2010
    Posts:
    38
    The SyncVar attribute synchronizes the variable with all observers/clients (unless I'm missing something) which is silly. The programmer should be able to control that.

    The way it should work:
    Code (csharp):
    1.  
    2. [SyncVar]//Sync to all observers by default
    3. public float health;
    4.  
    5. [SyncVar(rule=SyncRule.OwnerOnly)]//Sync armor only with the "Owner" of this object
    6. public float armor;
    7.  
    Code (csharp):
    1.  
    2. enum SyncRule
    3. {
    4.      All,
    5.      OwnerOnly,
    6.      ExceptOwner,
    7.      Conditional
    8. }
    9.  
    There is still a problem with team based games (like Counter Strike) where the health should not be synced for the opposite team. This is where the Conditional comes in.

    Code (csharp):
    1.  
    2. //Soldier.cs
    3. [SyncVar(rule=SyncRule.Conditional, condition="syncHealth")]
    4. public float health;
    5.  
    6. public bool syncHealth(NetworkConnection connection)
    7. {
    8.      return doesConnectionBelongToMyTeam(connection);
    9. }
    10.  
    The "syncHealth" method will only be called on the server. Lets say we have 2 players (Player1 and Player2), so we have two instances of the Soldier class on the server and clients. When the server is about to sync the Player1's health (to Player2 ) it would call syncHealth() and pass Player2's NetwrokConnection as the argument. If true is returned (evaluation succeeds), then the variable health is synced to Player2's instance of Player1's Soldier.
     
    Last edited: Jul 31, 2015
    Iron-Warrior likes this.
  2. pmurph03

    pmurph03

    Joined:
    Mar 17, 2014
    Posts:
    54
    Unless im misunderstanding how sync vars work, or possibly your question. I believe that the sync var is associated with the instance of the class it is associated with. So unless it is a static sync var, of which there can only be one instance of the value, there is no sharing between instances. Creating a owner only syncvar would simply just be a variable that is never synced to any other clients, like a regular variable that isnt labelled a syncvar. Note thaat I could be completely wrong but I imagine this is hkw syncvars work, as otherwise it does not seem to make sense to me.
     
  3. DWORD

    DWORD

    Joined:
    Jun 22, 2010
    Posts:
    38
    Everything that has a NetworkIdentity will be spawned for every client (if the server wants it to be spawned), assuming everything is visible to every player. When something is spawned the server assigns a unique network id for the NetworkIdentity component of the object that will be same on all clients, since that is how they identify each object.

    Using my "code" above as a reference, there would be two instances of Soldier on the server and on each client. But the server can "give control" of a object that has the NetworkIdentity to a player, so the player will be the "Owner" of the object. In this case the health variable will only be synced with the player that is the "Owner" and ignore every other client.

    Also, SyncVar doesn't work on static variables.
     
  4. pmurph03

    pmurph03

    Joined:
    Mar 17, 2014
    Posts:
    54
    There are definitely ways to program it ti function the way you would like it to using sync vars and other networking comoonents, that im sure with some effort and ingenuity you can figure out.

    I dont see any reason why you would want something important like health to go out of sync between clients though, but im sure yiu understanx your designs needs better than I do.

    Wish I could havd been more help, sorry.
     
  5. DWORD

    DWORD

    Joined:
    Jun 22, 2010
    Posts:
    38
    Can any of the UNet developers answer if/when you will implement something like this or if you guys can squeeze this in for 5.3?

    I'm asking this because I'm deciding which engine I will use and I need to plan ahead before the prototyping begins. If you guys can implement something like this for 5.3 I could start working on other parts of the project before I implement networking.

    Also, this Rule system would work the same way with the ClientRPC, I just didn't want to start a new topic to explain the same functionality.
     
  6. seanr

    seanr

    Unity Technologies

    Joined:
    Sep 22, 2014
    Posts:
    669
    Currently the state update messages that are sent for SyncVar changes are generated per-object, and sent to the set of observing players. To support this, dirty tracking is done per-object on the server. (State updates are technically per channel, per player, since NetworkBehaviours can specify a channel in NetworkSettings).

    To implement per-SyncVar visibility rules, different versions of these update messages would need to be generated per-player, and dirty tracking would also need to be done per-object, per-channel, per-player. This is on our list of features to do, but it is not a trivial change to do without impacting performance. It really should be done in a way that doesn't require all of the serialization logic to be run once for every observing player when the output would be the same, but still allow custom rules on a per-player basis.

    So it is planned, but there is no specific timeline.
     
    EAST-DATA likes this.