# 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:03 and onwards:

{% embed url="<https://youtu.be/kyUSiBpZ2Bc?t=63>" %}

Alternatively, you can follow the 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.

![](https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2FklEN6HKGKqZ8G31i7aph%2FScreenshot%202022-07-06%20at%2012.33.45.png?alt=media\&token=b9e2f7f3-da45-4156-9486-df2779f070c6)

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

![](https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2FXaktFMJzVwvcG0pbp5VI%2FScreenshot%202022-07-06%20at%2012.37.53.png?alt=media\&token=f2aee424-1eb5-46fa-aa22-b73d24049d85)

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.

![](https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2Fm1Z0pH0uPiup4B5Unbm5%2FScreenshot%202022-07-06%20at%2012.40.22.png?alt=media\&token=4a43a49c-bb2d-43cb-b3c7-2252a88b5358)

In this example, I'll be creating it on *Assets / Resources* by clicking **Convert to Prefab in Resources**.

![](https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2FK5OY63sfdHIrbyqnBxPG%2Fimage.png?alt=media)

#### **1.1 (Optional) Using 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 CoherenceSync to Cube, you can create a Cube (Networked) and add CoherenceSync to it:

{% hint style="info" %}
Learn how to create and use Prefab variants in the [Unity Manual](https://docs.unity3d.com/Manual/PrefabVariants.html).
{% endhint %}

<figure><img src="https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2FtPHcGqIH9twMPdg8CBCk%2FScreenshot%202022-09-07%20at%2015.47.02.png?alt=media&#x26;token=53b35b00-4a01-4ec9-bbb8-8658d19c41d8" alt=""><figcaption><p>Creating a variant of Cube</p></figcaption></figure>

<figure><img src="https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2FLgsGAceN788QdEedftQp%2FScreenshot%202022-09-07%20at%2015.47.20.png?alt=media&#x26;token=7452fad5-da24-485b-b13e-efdd37608a67" alt=""><figcaption><p>Adding CoherenceSync to the variant</p></figcaption></figure>

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.

<figure><img src="https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2FdV45QbuOb8Rb8V8JODTO%2Fimage.png?alt=media&#x26;token=4a4161e5-474c-4355-a892-4dc88272177b" alt=""><figcaption><p>Prefab variant with overriden synced variables</p></figcaption></figure>

### **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` will query 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 such as `PlayerInput` and even scripts that came with the Asset Store packages that you may have downloaded.

{% hint style="info" %}
You can find out more about CoherenceSync [here](https://docs.coherence.io/0.10/coherence-sdk-for-unity/components/coherencesync).
{% endhint %}

### **3. (Optional) Prefabs outside of the Resources folders**

In order for **coherence** to know which Prefab to instantiate through the network, they must be located in *Resources* folders or added to the `Prefab Mapper`. The `Prefab Mapper` is simply a ScriptableObject that holds Prefabs we want to sync.

When a `CoherenceSync` Prefab outside the Resources folder is not present in the Prefab Mapper, the *Add to Prefab Mapper* button appears.

![](https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2F3pavqTwrIDbexLPHWrF0%2FScreenshot%202022-07-06%20at%2012.48.56.png?alt=media\&token=0d716a57-978b-4155-bbf6-a36230e51edd)

{% hint style="info" %}
The Prefab Mapper asset is located at *Assets / coherence*.
{% endhint %}

#### 3.1. Addressables

If you are using the Addressables Package (1.15.0 or newer), the Prefab Mapper also supports that. The Prefab Mapper has a list for direct references and a list for addressables referenced using AddressableAssets.AssetReference. The directly referenced assets will be loaded at game start, while the addressables will be asynchronously loaded when needed.

Remember, in order for **coherence** to load assets as addressables, you need to follow Unity's default workflow for using Addressables which entails building the Addressables Group Bundles whenever the Prefab changes.

![](https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2F27B7h6NQ9XZzvZuhac5S%2FMapperMappings.png?alt=media)

#### 3.2. Prefab Mapper utilities

When adding a new Prefab to the mapper, it will automatically make sure to add it to the correct list (addressable or not), but if the Prefab already exists in the mapper and you have changed how it is loaded, simply press the *Validate Mapping Lists* button.

If you have a number of valid Prefabs that have not yet been added to the Prefab Mapper you can press the *Add all CoherenceSync prefabs* button.

If you have empty entries in the Prefab Mapper you can remove them by pressing *Remove empty entries*. This is optional.

![](https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2FNEnzoV4IuDwh202JQ2hI%2FMapperActions.png?alt=media)

### **4. Select variables to replicate**

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

Under *Configure*, click *Variables*.

![](https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2Fxa4AWuj3MsJVOeKyEQHf%2FScreenshot%202021-12-22%20at%2016.07.59.png?alt=media)

In the *Configuration* dialog, select *position, rotation and scale.*

![](https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2FZ5VNEDUhJkWd69Qe7Hrg%2FScreenshot%202021-12-22%20at%2016.09.03.png?alt=media)

{% hint style="info" %}
You can 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.
{% endhint %}

Close the *Configuration* dialog.

### **5. 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.

{% code title="Move.cs" %}

```csharp
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);
    }
}
```

{% endcode %}

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

### **6. 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 another Client where this object is not authoritative, but replicated? We will want the position to be replicated over the network, but without the keyboard input interfering with it.

Under *Configure*, click *Components*.

![](https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2Fq2zGY17HWs2PPKjCs8x0%2FComponent%20Actions.png?alt=media)

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.

![](https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2FxTqUEPzdgqgiCBkV3Fhp%2FDisable%20Move%20Component.png?alt=media)

### **7. Implementing your own Component Actions**

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

{% code title="ComponentAction.cs" %}

```csharp
using UnityEngine;

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

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

{% endcode %}

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:

{% code title="ComponentAction.cs" %}

```csharp
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;
    }
}
```

{% endcode %}

### **8. 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)

## Using the Coherence Hub

If you prefer, you can let the *Coherence Hub* guide you through your Prefab setup process. Simply select a Prefab, open the *Synced Object* tab in *Coherence Hub* and follow the instructions.

![coherence -> CoherenceHub](https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2FMDX3J76oWFSFlHe4zeh9%2FCoherenceHub_GameObjectTab_Status.png?alt=media)

<figure><img src="https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2FaHdI8riUevhpcpxZAccz%2Fimage.png?alt=media&#x26;token=8c5357f0-c2e2-45bd-a3e2-8191ab895946" alt=""><figcaption><p>coherence -> coherence Hub</p></figcaption></figure>

## Extras

{% hint style="info" %}
Helper scripts and samples can be found [here](https://docs.coherence.io/0.10/additional-resources/helper-scripts).
{% endhint %}

### **9. Constraints**

There are some constraints when setting up a Prefab with `CoherenceSync`, hereafter referred to as `Sync Prefab`.

1. A `Sync Prefab` has one, and only one `CoherenceSync` component in its hierarchy
2. The `CoherenceSync` component must be at the `Sync Prefab` root
3. A `Sync Prefab` cannot contain instances of other `Sync Prefabs`
4. A hierarchy in a scene can contain multiple `Sync Prefabs`. However, such a hierarchy cannot be saved as a `Sync Prefab` as that would break rule 1-3.

{% hint style="info" %}
Breaking rules 1-3 will lead to the build breaking in runtime.
{% endhint %}

#### 9.1. Examples of valid setup

![The ‘Car’ gameobject has the only CoherenceSync component in the hierarchy](https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2Fi4TuTYvCzHJR3jus2Xhd%2FAllowed%2001.png?alt=media)

![The ‘Car’ Prefab has multiple child Prefabs, but none of them are Sync Prefabs](https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2FwC0MCZHfaTUQlE0En2iP%2FAllowed%2002.png?alt=media)

![The ‘Wheel’ Sync Prefabs are placed under the ‘Car’ in the scene, but are not part of the ‘Car’ Sync Prefab itself](https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2FiMx0NJv22T36Zuof2TQr%2FAllowed%2003.png?alt=media)

#### 9.2. Examples of disallowed setup

![The ‘Car’ Sync Prefab has multiple wheels, which are Sync Prefabs themselves. This is not allowed](https://4229720839-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdBiAEtFeZKdAwRyJ9MEL%2Fuploads%2FymlMutDkWCHBsVClCEOE%2FDisallowed%2001.png?alt=media)
