This documentation is outdated.
SyncedVar's are a really powerful feature in the MLAPI. They originate from the HLAPI and inspiration is taken from there. They do however have fewer limitations in the MLAPI.
Any variable that is marked with the [SyncedVar] attribute and that is a part of a NetworkedBehaviour will be automatically replicated from the Server to Clients.
Limitations
Have no more than 255 SyncedVars per NetworkedBehaviour If you are willing to sacrifice another byte of overhead, you can up this limit to 65536. Open an issue if you need thisv1.2.0 has no limit- Have no more than 65536 NetworkedBehaviours per NetworkedObject
SyncedVars can only Sync these types as of now. But new ones can be added super easily. Open an issue if you need a type added.As of v1.2.2, any type can be used as long as it's a struct, class, primitive or an array. For classes and structs, they are passed through the BinarySerializer thus they are flattened out. Each struct is treated as it's own "thing". Chaning a field on a struct will cause the whole struct to resync. If you don't want a specific field to be synced in your struct or class. Use the BinaryIgnore attribute.Bool, Byte, Double, Single, Int, Long, SByte, Short, UInt, ULong, UShort, String, Vector3, Vector2, Quaternion, BoolArray, ByteArray, DoubleArray, SingleArray, IntArray, LongArray, SByteArray, ShortArray, UIntArray, ULongArray, UShortArray, StringArray, Vector3Array, Vector2Array, QuaternionArray
Notes
- Quaternion's are sent as the X,Y,Z components of the eulerAngles to save space. (3 floats)
- Vector3's are sent as X,Y,Z (3 floats)
- Vector2's are sent as X,Y (2 floats)
Arrays have two extra bytes sent once it's synced. They are encoded as varintsArrays have the whole array is synced and not just the changes- Arrays in v.1.2.3 and later work very differently from earlier versions. If they are purley single dimension (I.E there is no other array above them. See * below) each time you Resize an array it will be completley resynced, the whole array will be resent. However, if you just change values on the array, only that value will be resent along with a few extra bits (not bytes) to work as a dirty mask for the array.
- Arrays have a size limit of 65536 bytes.
- Arrays are only supported in version v1.0.2 and later with the exception of byte array.
*If you have an array of structs, where each struct contains an array. That array will not have diff sending enabled as it's not the root array
Each NetworkedObject controls the NetworkedBehaviours that's child of it. You can not add, remove or reorder the NetworkedBehaviours of an NetworkedObject. You can however add NetworkedObjects as child of other NetworkedObjects and thus new NetworkedBehaviours can be added.
Important note
The ORDER of the NetworkedBehaviours needs to be the same across all projects (if you use different ones). The order is the order the NetworkedBehaviours gets reported by the GetComponentsInChildren method. The SyncedVar fields also needs to have the same NAMES. The fields gets sorted by their name.
Sync
Sync behaviour
On every NetworkedBehaviour there is a SyncedVarDelay that can be adjusted. The SyncedVarDelay is the delay between SyncedVar checks. A SyncedVar check has multiple stages. The first one is dirty marking. Each field can be "dirty". If a field is dirty, it means it needs to be synced. After the fields have been marked, every dirty field is synced. Note that this is the most basic behaviour, certain internal parts work slightly differently to work with for example the observer system. For that, each SyncedVar has a list of "observer dirty" clients, clients that are dirty because they were not observing the last sync. If the SyncVarDelay is set to a negative value, a sync will only happend when the object is created.
First Sync
The first sync happends during object spawn, this is to ensure that all syncedVars are ready to be used on clients straight away when a object gets spawned. This initial sync will happend even if SyncDelay is negative.
Hooks
SyncedVars can have "hooks". This is a method that will get invoked after a syncedVar value has been changed. Simply pass the MethodName of the method to invoke in the attribute.
[SyncedVar(hook = "MyMethod")]
Target
The Target feature is only avalible in versions > v1.0.0
SyncedVars can be "targeted". This means that the SyncedVar will only be sent to the client that owns a certain object. This will drastically save bandwidth for variables that doesn't need to be synced to everyone. It does however have a performance cost when syncing targeted SyncedVars, this is because two Sync messages has to be created for every NetworkedBehaviour. One for non owners that only contains SyncedVars are not targeted. And one including every dirty field. This cost is however very minor.
Usage:
[SyncedVar(target = true)]
Performance
The SyncedVar system is built using reflection and lots of boxing, it can therefor be very slow compared to weaver based implementations. It's recommended to really think about the syncDelay value for this reason, to prevent unneccecary checking by reflecftion and boxing. Values that are updated very frequently, ex positions are therefor better suited for the message system.
Getting Started
The Basics
- Message System
- Object Spawning
- Object & Behaviour Relation
- Modularity
- NetworkedVar
- Scene Management
- Object Ownership
Components
Advanced Topics
- Encryption
- Networked Object Pooling
- Lag Compensation
- BitWriter & BitReader
- Custom Transports
- Optimization
- Network Profiler Window
- Dedicated Servers