# 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:

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

## Using the coherence Hub

You can let the &#x63;_&#x6F;herence 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.

<figure><img src="https://976449006-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4xmLLczbgaGVeoF6vews%2Fuploads%2FZSlzDMNLgDZ1kRM3guku%2FCoherenceHub_ObjectSetup.png?alt=media&#x26;token=aac5ac3e-7920-42a6-80a7-45f7dfeffa76" alt="" width="563"><figcaption></figcaption></figure>

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

![](https://content.gitbook.com/content/4xmLLczbgaGVeoF6vews/blobs/bZcNt3T1mDcLVoiZLt3i/Screenshot%202022-07-06%20at%2012.33.45.png)

Next, we add the `CoherenceSync` component to **Cube**.

![](https://content.gitbook.com/content/4xmLLczbgaGVeoF6vews/blobs/69EXpZapXlsWkagAaLSm/Screenshot%202022-07-06%20at%2012.37.53.png)

`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://976449006-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4xmLLczbgaGVeoF6vews%2Fuploads%2FG1Od5bOtgbuOVAz97ETy%2FCoherenceSync_NotConfigured.png?alt=media\&token=eff07cf1-f2af-4101-8918-3f5d67bcb9cf)

### (Optional) Networking an already existing Prefab

If you wish to start networking a Prefab that already exists in your project, you have several options to do it. Remember that they all lead to the same result.

You can:

* Click on the _Sync with coherence_ checkbox at the top of the Prefab inspector.

<figure><img src="https://976449006-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4xmLLczbgaGVeoF6vews%2Fuploads%2FTLXSY4O06Fya5RPKueyo%2FSyncWithCoherence_Checkbox.png?alt=media&#x26;token=a3400ef8-ecc8-46d9-b6b2-800c348c064a" alt="" width="563"><figcaption></figcaption></figure>

* Manually add the `CoherenceSync` component.

<figure><img src="https://976449006-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4xmLLczbgaGVeoF6vews%2Fuploads%2FAFhJoz7mkJ5hwsVa3Ceu%2FAddCoherenceSync.png?alt=media&#x26;token=ab8ada3d-6b8e-447c-b390-1a66e1b79ba2" alt="" width="563"><figcaption><p>Networking an existing Prefab</p></figcaption></figure>

* Drag the Prefab to the _CoherenceSync Objects_ window. You can find it in _coherence > CoherenceSync Objects_.

<figure><img src="https://976449006-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4xmLLczbgaGVeoF6vews%2Fuploads%2FTMyIoGIVcvqyvnpTabLJ%2FAddToSyncObjects.gif?alt=media&#x26;token=b6d41947-bb21-43ca-b5a2-ef4da8a0042c" alt=""><figcaption></figcaption></figure>

### **(Optional) Prefab variants**

One way to configure your Prefab instead of just adding `CoherenceSync` to 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)** Prefab 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 %}

This way, you can retain the original Prefab untouched, and build all the network functionality separately, in its own Prefab.

<figure><img src="https://content.gitbook.com/content/4xmLLczbgaGVeoF6vews/blobs/KImMTUCHry2CqWX7zZoe/Screenshot%202022-09-07%20at%2015.47.02.png" alt=""><figcaption><p>Creating a variant of Cube</p></figcaption></figure>

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

The Prefab variant inherits the network settings from its parent, and you change those 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 line next to it, just like any other override in Unity:

<figure><img src="https://976449006-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4xmLLczbgaGVeoF6vews%2Fuploads%2FCdLhH6WEas3OCTC1ZyVV%2FPrefabVariantConfig.png?alt=media&#x26;token=b5955092-ab97-4668-9789-b9873ac017c7" alt="" width="563"><figcaption><p>Prefab variant with a few overriden synced properties</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.

<figure><img src="https://976449006-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4xmLLczbgaGVeoF6vews%2Fuploads%2FEsDPLauUjSzApsmirp5l%2FCoherenceSync_Inspector.png?alt=media&#x26;token=135c09e1-1076-4af1-9947-820b897409f7" alt="" width="563"><figcaption><p>CoherenceSync inspector</p></figcaption></figure>

In its Inspector you can configure settings for **Lifetime** (_Session-based_ or _Persistent_), **Authority transfer** (_Not Transferable_, _Request_ or _Steal_), **Simulate In** (_Client Side_, _Server Side_ or _Server Side with Client Input_) and **Adoption** settings for when persistent entities become orphaned, and more.

There are also a host of **Events** that are triggered at different times.

{% hint style="info" %}
Its Inspector has quite a number of settings. For more information on them, refer to [the `CoherenceSync` page](../coherence-sdk-for-unity/components/coherencesync).
{% endhint %}

For now, we can leave these settings to their defaults.

### **2.1 Select variables to replicate**

`CoherenceSync` allows you to **automatically network all public variables** and methods on any of the attached components, from Unity components such as `Transform`, `Animator` , etc. to any custom script, including scripts that came with the Asset Store packages that you may have downloaded.

To set it up, click on the _Configure_ button in the `CoherenceSync`'s Inspector. This brings up the _Configuration_ window. Here you can select which variables you would like to sync across the network:

<figure><img src="https://976449006-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4xmLLczbgaGVeoF6vews%2Fuploads%2FguN7EuVcIpgiVkd5lzdc%2FConfigureWindow_BaseProperties.png?alt=media&#x26;token=8520d454-8c4a-4be4-95e2-7c0af2918aeb" alt="" width="563"><figcaption><p>Configure Window</p></figcaption></figure>

You will notice that **position** is already selected, and can't be removed. For our use case, let's add **rotation** and **scale**_._

{% hint style="info" %}
Note that you can configure variables, methods and components not only on the root, but also [on child GameObjects](../coherence-sdk-for-unity/networking-state-changes/child-gameobjects).
{% endhint %}

Close the _Configuration_ dialog.

### **3. Add a movement script**

This simple movement 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 to the Prefab.

### **4. Disable the component on replicated objects**

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 want the position to be replicated over the network **without keyboard input interfering** with it.

In the _Configuration_ window, click the _Components_ tab:

![](https://976449006-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4xmLLczbgaGVeoF6vews%2Fuploads%2Fftz06kG8DMBlxF8d67b6%2FComponentActions.png?alt=media\&token=6c7599c7-d9ee-4554-a35b-d0199a1c3ca3)

Here you will see a list of Component Actions that you can apply **to non-authoritative entities** 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://976449006-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4xmLLczbgaGVeoF6vews%2Fuploads%2F7XmQYSFLyz5ZQ7gyDuFh%2FComponentActionDisabled.png?alt=media\&token=d18fdf46-e2e4-453c-af37-bd121d9a6ea9)

This ensures that, if a copy of this Prefab is instantiated on a Client with no authority, this script will be disabled and won't interfere with the position that is being synced on the network.

### 5. Bake the netcode

Once everything is setup, you should ensure to run the process of [Baking](../coherence-sdk-for-unity/baking-and-code-generation): coherence will produce the necessary netcode (i.e. a bunch of C# scripts) to ensure that when the game is running and the Client connects, all of the properties and network messages you might have configured will correctly sync.

This process is very quick, and can be done in different ways:

* From the menu item _coherence > Bake_
* Within the coherence Hub, in the _Baking_ tab, using **Bake Now**:

<figure><img src="https://976449006-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4xmLLczbgaGVeoF6vews%2Fuploads%2FYJ8DV9yH2Nk1oxXXhLk0%2FBakingFromTheHub.png?alt=media&#x26;token=7d9bc763-f940-4cfb-8088-02183542a117" alt="" width="563"><figcaption><p>If the Bake Now button has a warning, you need to bake before running the game</p></figcaption></figure>

* When a Prefab contains changes that need baking, its Inspector will warn you. Pressing **Bake** here will actually bake all code for all Prefabs:

<figure><img src="https://976449006-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F4xmLLczbgaGVeoF6vews%2Fuploads%2FDRmfsragWhQfwktRrdZR%2FNeedToBake.png?alt=media&#x26;token=40fe5bb7-ef26-4348-a2d7-29ec2c97af3f" alt="" width="563"><figcaption></figcaption></figure>

### To recap

In short, setting up a Prefab for networking requires:

* A Prefab with a `CoherenceSync` added to it
  * Optionally, setting some of its properties
* Configuring what to sync in the _Configure_ window
* Disabling components on remote entities, in the _Configure > Components_ tab
* Baking the netcode

{% hint style="success" %}
This is it! Setting up a Prefab to be networked doesn't require additional steps.

Now you can run this setup [locally](build-and-run) or using the [coherence Cloud](coherence-cloud).
{% endhint %}

## Helper scripts

{% hint style="info" %}
Helper scripts and samples can be found [here](../additional-resources/helper-scripts). 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&#x20;
* Implementing Network Commands and Authority Transfer
* Connection Events
{% endhint %}
