Defines a network entity and what data to sync from the GameObject. Anything that needs to be synchronized over the network can use a CoherenceSync component. You can select data from your GameObject hierarchy that you'd like to sync across the network.
Queries an area of interest, so that you can read/write across the network on the desired location. In our Starter Project, the LiveQuery position is static with an extent large enough to cover the entire playable level. If the World was very large and potentially set over multiple Simulators, the LiveQuery could be attached to the playable character or camera.
Handles the connection between the coherence transport layer and the Unity scene.
Enables a Simulator to take control of the state authority of a Client's CoherenceSync, while retaining input authority.
This component is added by CoherenceSync on server-authoritative setups.
In addition to the LiveQuery, coherence also supports filtering objects by tag. This is useful when you have some special objects that should always be visible regardless of World position.
For a guide on how to use TagQuery, see Areas of Interest.
The Bridge establishes a connection between your scene and the coherence Replication Server. It makes sure all networked entities stay in sync.
When you place a GameObject in your scene, the Bridge detects it and makes sure all the synchronization can be done via the CoherenceSync
component.
At runtime, you can inspect which Entites the Bridge is currently tracking.
A Bridge is associated with the scene it's instantiated on, and keeps track of Entities that are part of that scene. This also allows for multiple connections at the same time coming from the game or within the Unity Editor.
The CoherenceBridge offers a couple of Unity Events in its inspector where you can hook your custom game logic:
This event is invoked when the Replication Server state has been fully synchronized, it is fired after OnConnected.
For example, if you connect to a ongoing game that has five players connected, when this event is fired all the entities and information of all the other players will already be synchronized and available to be polled.
This event is invoked the moment you stablish a connection with the Replication Server, but before any synchronization has happened.
Following the previous example, if you connect to an ongoing game that has five players connected, when this event is fired, you won't have any entities or information available about those five players.
This event is invoked when you disconnect from a Replication Server. In the parameters of the event you will be given a ConnectionCloseReason value that will explain why the disconnection happened.
This event is invoked when you attempt to connect to a Replication Server, but the connection fails, you will be returned a ConnectionException with information about the error.
The Client Connections system allows you to keep track of how many users are connected and uniquely identify them, as well as easily send server-wide messages.
You can read more about the Client Connections system here.
If you have a Developer Portal account, you can connect to Worlds or Rooms hosted in coherence Cloud. You can use the CloudService instance from CoherenceBridge to fetch existing Worlds or create or fetch existing Rooms, after you fetch a valid World or Room, you can use the JoinWorld or JoinRoom methods to easily connect your client.
You can read more about the Unity Cloud Service here.
Currently, the maximum number of persistent Entities supported by the Replication Server is 32 000. This limit will be increased in the near future.
The way you get information about the World is through LiveQueries. We set criteria for what part of the World we are interested in at each given moment. That way, the Replicator won’t send information about everything that is going on in the Game World everywhere, at all times.
Instead, we will just get information about what’s within a certain area, kind of like moving a torch to look around in a dark cave.
For a guide on how to use LiveQuery, see .
More complex areas of interest types are coming in future versions of coherence.
CoherenceSync
is a component that should be attached to every networked GameObject. It may be your player, an NPC or an inanimate object such as a ball, a projectile or a banana. Anything that needs to be synchronized over the network and turned into an Entity. You can then select which of the attached public properties and methods of other components you would like to sync across the network.
To start syncing variables and commands, open the Configure window that you can access from the CoherenceSync inspector:
Any components attached to the GameObject with CoherenceSync
that have public variables will be shown here and can be synced across the network. Enable the script + the variable to sync, it's that easy.
When you create a networked GameObject, you automatically become the owner of that GameObject. That means only you are allowed to update or destroy it. But sometimes it is necessary to pass ownership from one player to another. For example, you could snatch the football in a soccer game or throw a mind control spell in a strategy game. In this case, you will need to transfer ownership from one Client to another.
When a player disconnects, all the GameObjects created by that player are usually destroyed. If you want any GameObjects to stay in the Game World after the owner disconnects, you need to set Entity lifetime type of that GameObject to Persistent.
Session Based - will be removed when the Client disconnects. GameObjects will stay on the scene of the Client who is an Authority owner for session-based objects until the scene reloads.
Keep in mind that Entity IDs are assigned locally. This means that the IDs for the same Entity can be different on different Clients.
Allow Duplicates - no restrictions on which objects can be instantiated over the network.
No Duplicates - ensure objects are not duplicated by assigning them a Unique ID.
You can set the Unique ID manually in the Prefab, only one Prefab instance will be allowed at runtime, any other instance created with the same UUID will be destroyed.
When creating a Prefab instance in the Scene at Editor time, a special Prefab Instance Unique ID is assigned, if the manual UUID is blank, the UUID assigned at runtime will be the Prefab Instance ID:
Uniqueness examples
Manager: If your game has a Prefab, of which there can only be 1 in-game instance at any time (Such as a Game Controller), assign a UUID manually on the Prefab asset.
Interactable objects: If you have several instances of a given Prefab, but each instance must be unique (Such as doors, elevators, pickups, etc.), each instance created in Editor time will have a auto-generated Prefab Instance Unique ID. This means that i.e. a door will only spawn once, but still replicate its state across the network.
Entity simulation type
Client Side - Simulates everything on the local Client and passes the information to the Replication Server to distribute that information to the other Clients.
Other forms of simulation (Server; Server with Client Input).
Authority transfer style
Not Transferable - The default value is Not Transferable because most often objects are not meant to be transferred.
Stealing - Allows the GameObject to be transferred to another Client.
Request - This option is intended for conditional transfers, which is not yet supported.
Orphaned entities
By making the GameObject persistent, you ensure that it remains in the game world even after its owner disconnects. But once the GameObject has lost its owner, it will remain frozen in place because no Client is allowed to update or delete it. This is called an orphaned GameObject.
In order to make the orphaned GameObject interactive again, another Client needs to take ownership of it. To do this, enable Auto-adopt orphan.
Once you have set the transfer style to Stealing, any Client can request ownership by calling the RequestAuthority()
method on the CoherenceSync
component of that GameObject:
someGameObject.GetComponent<CoherenceSync>().RequestAuthority();
A request will be sent to the GameObject's current owner. The current owner will then accept the request and complete the transfer.
You are now the new owner of the GameObject. This means the isSimulated
flag has been set to true, indicating that you are now in full control of the GameObject. The previous owner is no longer allowed to update or destroy it.
The state of the CoherenceSync.isSimulated
flag is not guaranteed to have a proper value during the Awake()
callback (right after an object is created). All scripts that use this flag should wait at least until the Start()
callback.
You can set up Custom Events for handling user connection and disconnection. Manual Destroy is useful for session based objects that you want to keep "semi-persistent" which would be removed when all the Clients disconnect.
When CoherenceSync
variables/components are sent over the network, by default, Reflection Mode is used to sync all the data at runtime. Whilst this is really useful for prototyping quickly and getting things working, it can be quite slow and unperformant. A way to combat this is to bake the CoherenceSync component, creating a compatible schema and then generating code for it.
The schema is a file that defines which data types in your project are synced over the network. It is the source from which coherence SDK generates C# struct types (and helper functions) that are used by the rest of your game. The coherence Replication Server also reads the schema file so that it knows about those types and communicates them with all of its Clients efficiently.
The schema must be baked in the coherence Settings window, before the check box to bake this Prefab can be clicked.
When the CoherenceSync
component is baked, it generates a new file in the baked folder called CoherenceSync<AssetIdOfThePrefab>
. This class will be instantiated at runtime, and will take care of networked serialization and deserialization, instead of the built-in reflection-based one.
Commands are public methods from Components that are marked as synced in the Configure window.
Persistence - Entities with this option will persist as long as the server is running. For more details, see .
with a custom implementation of authority transfer can be found here.
Refer to the section.
You might also want to check out the CoherenceSync instance lifecycle section at the bottom of the article.
This page describes the order of various coherence events and scripts in relation to Unity's main loop.
Check out ScriptExecutionOrder.
Additionally, take a look at your project's Script Execution Order settings by opening Edit > Project Settings and selecting the Script Execution Order category. See this Unity manual article for more details.
Depending on the reason for a disconnection the onDisconnected
event can be raised from different places in the code, including LateUpdate
.
When a Prefab instance with CoherenceSync is created at runtime, it will be fully synchronized with the network in the OnEnable method of CoherenceSync. This means that you can expect your custom Components to have fully resolved synchronized values and authority state in your Awake method. It occurs in the following order:
Awake() is called
Internal initialization.
OnEnable() is called
Synchronize with a new or existing Network Entity.
OnBeforeNetworkedInstantiation event is invoked.
Initial component updates are applied (for entities you have no authority over).
OnNetworkedInstantiation event is invoked.
OnStateAuthority or OnStateRemote (for authority or non-authority instances respectively) event is invoked.
Awake() is called
At this point, if you get the CoherenceSync component, you can expect networked variables and authority state to be fully resolved.