Object Spawning
Remote Actions

State Synchronization

SyncVars

SyncVars are member variables of NetworkBehaviour scripts that are synchronized from the server to clients. When an object is spawned, or a new player joins a game in progress, they are sent the latest state of all SyncVars on networked objects that are visible to them. Member variables are made into SyncVars by using the [SyncVar] custom attribute:

class Player : NetworkBehaviour
{

    [SyncVar]
    int health;

    public void TakeDamage(int amount)
    {
        if (!isServer)
            return;

        health -= amount;
    }
}

The state of SyncVars is applied to objects on clients before OnStartClient() is called, so the state of the object is guaranteed to be up-to-date inside OnStartClient().

SyncVars can be basic types such as integers, strings and floats. They can also be Unity types such as Vector3 and user-defined structs, but updates for struct SyncVars are sent as monolithic updates, not incremental changes if fields within a struct change.

SyncVar updates are sent automatically by the server when the value of a SyncVar changes. There is no need to perform any manual dirtying of fields for SyncVars.

SyncLists

SyncLists are like SyncVars but they are lists of values instead of individual values. SyncList contents are included in initial state updates with SyncVar state. SyncLists do not require the SyncVar attributes, they are specific classes. There are built-in SyncList types for basic types:

  • SyncListString
  • SyncListFloat
  • SyncListInt
  • SyncListUInt
  • SyncListBool

There is also SyncListStruct which can be used for lists of user-defined structs.

Custom Serialization

Often the use of SyncVars is enough for scripts to serialize their state to clients, but some cases require more complex serialization code. The virtual functions on NetworkBehaviour that are used for SyncVar serialization can be implmented by developers to perform their own custom serialization. These functions are:

public virtual bool OnSerialize(NetworkWriter writer, bool initialState);
public virtual void OnDeserialize(NetworkReader reader, bool initialState);

If the OnSerialize function returns true, this means that the object was dirty and an update should be sent.

The initialState flag is useful to differentiate between the first time an object is serialized and when incremental updates can be sent. The first time an object is sent to a client, it must include a full state snapshot, but subsequent updates can save on bandwidth by including only incremental changes.

The OnSerialization method will only be invoked on an instance on the server if it is dirty. NetworkBehaviour components can be set dirty by calling SetDirtyBit() on them. This function takes a binary mask that is OR’ed with the current dirty state of the object. This mask is available inside OnSerialize as syncVarDirtyBits. It is automatically reset when OnSerialize returns true. This can be used for doing compact incremental state updates. Note that changing the value of a SyncVar member variable automatically sets dirty bits on that instance, so there is no need to call SetDirtyBit() manually in that case.

If a class has SyncVars, then implementations of these functions are added automatically to the class. So a class that has SyncVars cannot also have custom serialization functions.

Object Spawning
Remote Actions