Why is this public variable the same on client and server?

This isn’t a big deal but I noticed some odd behavior. In my code I have a NetworkManager, with a script attached. It has a Network View but it’s set to State Synchronization=Off, Observed=None. My “client” and my “server” are actually in the same project.

I wanted to make sure the user doesn’t try to connect a client that is a different version than the server. So I created a:

public float myClientOrServerVersion = 0.16f;

Then I build the server with that. Then I change the number to 0.17. Then I build the client. The problem is that when it runs, both the client and server think it’s 0.16. Somehow Unity is forcing my client’s value of the variable to be the same as the server! But my understanding is the client and server keep their own variables, even when there’s a Network View in play. And I get that a “public” variable is like a global; it is visible to other code. But even over the network?

When I change the variable definition to:

static float myClientOrServerVersion = 0.16f;

Then the code works: using RPC I’m able to differentiate the client and server versions.

If I’m right and this is weird behavior, let me know and I can enter it into the issue tracker. BTW I didn’t search to see if this issue was already found.

Well, the answer is simple :smiley:

You stepped into the “serialization trap”. public variables are serialized by Unity. That way you can edit them in the inspector and they have their value saved. Changing the field-initializer in the script won’t change anything since Unity deserializes the variable from the serialized data. If you want to specify the value in the script, don’t let Unity serialize this variable by:

  • make the variable private.
  • adding the NonSerialized attribute to your variable
  • make it a property

The usual way is to declare such varibles private. If you need access from outside, either use a get-method (GetVersion for example) or use a property:

    private float m_Version = 0.16f;
    public float Version
    {
        get { return m_Version; }
    }

or simply:

    public float Version
    {
        get { return 0.16f; }
    }