Prefab Setup: CoherenceSync

In this section, we will learn how to prepare a Prefab for network replication.

Video tutorial

Setting up basic syncing is explained in this video, from 1:00 and onwards:

Using the Coherence Hub

You can let the coherence Hub guide you through your Prefab setup process. Simply select a Prefab, open the GameObject tab in the coherence Hub (coherence > coherence Hub) and follow the instructions.

Step by step

You can also follow the detailed step-by-step text guide below.

1. Add CoherenceSync to your GameObject

For a Unity GameObject to be networked through coherence, it needs to have a CoherenceSync component attached. Currently, only Prefabs are supported. If your GameObject is not a Prefab, CoherenceSync can assist you.

First, create a new GameObject. In this example, we're going to create a Cube.

Next, let's add the CoherenceSync component to this Cube.

The CoherenceSync inspector now tells us that we need to make a Prefab out of this GameObject for it to work. We get to choose where to create it.

In this example, we'll be creating it in 📁 Assets / Resources by clicking Convert to Prefab in Resources.

1.1 Networking an already existing Prefab

If you wish to start networking a Prefab that already exists in your project, you have more options to get started:

  • Clicking on the Sync with coherence checkbox at the top of the Prefab inspector.

  • Manually adding the CoherenceSync component.

  • Drag the Prefab to the CoherenceSync Objects Window you can find in coherence > CoherenceSync Objects.

1.2 (Optional) Prefab variants

One way to configure your Prefab, instead of just adding CoherenceSync into it, is to fork a Prefab variant and add the component there.

In our Cube example, instead of adding the component to the original Prefab, you can create a variant called Cube (Networked) and add CoherenceSync to it:

Learn how to create and use Prefab variants in the Unity Manual.

This way, you can retain the original Prefab untouched.

Another way to use Prefab variants to our advantage is to have a base Prefab using CoherenceSync, and create Prefab variants off that one with customizations. For example, Enemy (base Prefab) and Enemy 1, Enemy 2, Enemy 3... (variant Prefabs, using different models, animations, materials, etc.). In this setup, all of the enemies will share the networking settings stored in CoherenceSync, so you don't have to manually update every one of them.

When the Prefab variant inherits the network settings from the Prefab parent, you can configure your Prefab variant with overrides in the Configuration window. When a synced variable, method or component action is present in the variant and not in the parent, it will be bolded and it will have the blue prefix beside it, just like any other override in Unity.

2. Configure CoherenceSync

The CoherenceSync component will help you prepare an object for network synchronization during design time. It also exposes an API that allows us to manipulate the object during runtime.

CoherenceSync scans all public variables and methods on any of the attached components, for example Unity components such as Transform, Animator , etc. This will include any custom scripts and even scripts that came with the Asset Store packages that you may have downloaded.

You can find out more about all of CoherenceSync properties here.

3. Select properties to replicate

Select which properties you would like to sync across the network. Initially, this will probably be the Transform properties: position, rotation, scale.

Click the Configure button in the CoherenceSync Inspector. A new window will open, called Configuration.

Click on the tab Variables. Since position is already selected, add rotation and localScale.

Close the Configuration window.

Tip: You can also configure variables, methods and components on child objects in the CoherenceSync hierarchy. To do that, simply select the desired object in the Hierarchy window, and the Configuration window will show information for that specific object — similarly to how the Inspector works.

4. Add an input script

This simple input script will use WASD or the Arrow keys to move the Prefab around the scene.

Click on Assets > Create > C# Script.

Name it Move.cs. Copy-paste the following content into the file.

Move.cs
using UnityEngine;

public class Move : MonoBehaviour
{
    public float speed = 1f;

    void Update()
    {
        float h = Input.GetAxisRaw("Horizontal");
        float v = Input.GetAxisRaw("Vertical");
    
        var spf = speed * Time.deltaTime;

        transform.position += transform.forward * (v * spf);
        transform.position += transform.right * (h * spf);
    }
}

Wait for Unity to compile the file, then add it onto the Prefab.

5. Disable input on replicated object

We have added a Move script to the Prefab. This means that if we just run the scene, we will be able to use the keyboard to move the object around.

But what happens on other Clients where this object is not authoritative, but replicated? We will want the position to be replicated over the network, without the keyboard input interfering with it.

Under Configure, click Components.

Here you will see a list of Component Actions that you can apply to non-authoritative GameObjects that have been spawned by the network.

Selecting Disable for your Move script will make sure the Component is disabled for network instances of your Prefab.

6. Implementing your own Component Actions

By extending the ComponentAction abstract class, you can implement your own Component Actions.

ComponentAction.cs
using UnityEngine;

[System.Serializable]
public abstract class ComponentAction
{
    [SerializeField] internal Component component;
    public Component Component => component;

    public virtual void OnAuthority() { }
    public virtual void OnRemote() { }
}

Your custom Component Action must implement the following methods:

  • OnAuthority This method will be called when the object is spawned and you have authority over it.

  • OnRemote This method will be called when a remote object is spawned and you do not have authority over it.

It will also require the ComponentAction class attribute, specifying the type of Component that you want the Action to work with, and the display name.

For example, here is the implementation of the Component Action that we use to disable Components on remote objects:

ComponentAction.cs
using Coherence.Toolkit;
using UnityEngine;

[ComponentAction(typeof(Behaviour), "Disable")]
public class DisableBehaviourComponentAction : ComponentAction
{
    public override void OnAuthority()
    {
        var b = Component as Behaviour;
        b.enabled = true;
    }

    public override void OnRemote()
    {
        var b = Component as Behaviour;
        b.enabled = false;
    }
}

7. Additional CoherenceSync settings

From the CoherenceSync component you can configure settings for Lifetime (Session-based or Persistent, Authority transfer (Request or Steal), Simulation model (Client Side, Server Side or Server Side with Client Input) and Adoption settings for when local persistent entities are orphaned.

There are also some Events that are triggered at different times.

  • On Before Networked Instantiation (before the GameObject is instantiated)

  • On Networked Instantiation (when the GameObject is instantiated)

  • On Networked Destruction (when the GameObject is destroyed)

  • On Authority Gained (when authority over the GameObject is transferred to the local client)

  • On Authority Lost (when authority over the GameObject is transferred to another client)

  • On After Authority Transfer Rejected (when GameObject's Authority transfer was requested and denied).

  • On Input Simulator Connected (when client with simulator is ready for Server-side with Client Input)

  • On Input Owner Assigned (when InputOwner was changed is ready)

8. Nested CoherenceSync components

It is possible to nest network entities into each other both at edit and at runtime. Doing it at runtime is semi-automatic, and only if you nest an entity deeply into a hierarchy (like a tool in the hands of a character), you need to add the CoherenceNode component to the nested one.

For edit-time nesting instead, the PrefabSyncGroup needs to be placed on the root object.

Helper scripts

Helper scripts and samples can be found here. These cover things such as:

  • Spawning a player

  • Basic inputs to get Game Objects moving

  • Score keeper

  • Displaying player names

  • Camera facing UI

  • Off-screen spawning of enemies or other Game Objects

  • Indicator (arrow) for guiding the player towards off-screen Game Objects

  • Implementing Network Commands and Authority Transfer

  • Connection Events

Last updated