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:
[SyncVar]//Sync to all observers by default
public float health;
[SyncVar(rule=SyncRule.OwnerOnly)]//Sync armor only with the "Owner" of this object
public float armor;
enum SyncRule
{
All,
OwnerOnly,
ExceptOwner,
Conditional
}
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.
//Soldier.cs
[SyncVar(rule=SyncRule.Conditional, condition="syncHealth")]
public float health;
public bool syncHealth(NetworkConnection connection)
{
return doesConnectionBelongToMyTeam(connection);
}
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.
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.
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.
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.
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.
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.