LogoLogo
⚠️ Outdated documentationGo to LatestHomeAPI
SDK 1.0
SDK 1.0
  • Welcome
  • Overview
    • What is coherence?
    • How does coherence work?
    • Rooms and Worlds
    • Features and Roadmap
    • Release Notes
    • Known Issues and Troubleshooting
  • Learning coherence
    • Beginner's Guide to Networking Games
    • First Steps tutorial
      • 1. Basic syncing
        • 1.2. Animation parameters
        • 1.3. Sending commands
      • 2. Physics / Authority transfer
      • 3. Areas of interest
      • 4. Parenting entities
      • 5. Complex hierarchies
      • 6. Persistence
    • Campfire project
      • Game mechanics
      • Leveraging object pooling
      • Remote interactions: Chairs
      • Remote interactions: Trees
      • A unique object with complex state
      • Custom instantiation and destruction
      • Running a server-side NPC
      • Playing audio and particles
      • A simple text chat
    • How to network...
      • Racing
      • Turn-based
      • First-Person Shooter
      • MMO
      • Fighting
  • Get started
    • Installation
    • Scene Setup
      • Samples
    • Prefab Setup: CoherenceSync
    • Local Development
      • Tips and Recommendations
    • coherence Cloud
      • Create a Free Account
      • Deploy a Replication Server
      • Share Builds
  • coherence SDK for Unity
    • Components
      • CoherenceSync
      • CoherenceBridge
      • CoherenceLiveQuery
      • CoherenceTagQuery
      • Order of execution
    • Asset Management
      • Using CoherenceSyncConfig to instantiate GameObjects locally
      • CoherenceSyncConfigRegistry Save Modes
    • Networking State Changes
      • Messaging with Commands
      • Hierarchies & Child Objects
        • Child GameObjects
        • Child CoherenceSyncs
        • Deep Child CoherenceSyncs
      • Animations
      • CoherenceSync References
      • [Sync] and [Command] Attributes
      • [OnValueSynced] Attribute
      • Supported Types
      • Creating your own syncable member
    • Baking (Code Generation)
    • Scene Management
    • Authority
      • Authority transfer
      • Server-authoritative setup
    • Lifetime
      • Persistence
      • Example – a global counter
    • Optimization
      • Simulation Frequency
      • Areas of Interest
      • Level of Detail (LOD)
    • Profiling
    • Interpolation
    • Rigid Bodies
    • Settings
    • Simulation Frame
    • Replication Server
    • Simulators
      • Scripting: Client vs Simulator
      • Local Development
      • World Simulators
      • Room Simulators
      • Simulator Slugs
      • Multi-Room Simulators
      • Build and Publish
      • Command-line arguments
      • Load Balancing
    • Client-Hosting
    • Client Connections
    • Rollback Networking Support
    • World Origin Shifting
    • CLI
    • Upgrading Unity SDK
      • Upgrading to coherence Unity SDK 1.0.0
      • Upgrading to coherence Unity SDK 0.9.0
  • coherence Cloud
    • Developer Portal
    • Dashboard
    • Worlds
    • Rooms
    • Lobbies
    • Game Services
      • Account
      • Key-Value Store
    • Using coherence Cloud in Unity
      • Worlds
      • Rooms
      • Lobbies
      • Game Services
        • Authentication Service (Player Accounts)
        • Key-value store
  • Schema explained
    • Overview
    • Specification
    • Field settings
    • Archetypes
  • coherence Scripting API
  • Additional resources
    • Community
    • Quick Samples
    • Continuous Integration
    • Unreal Engine Support
    • WebGL Support
    • Peer-to-Peer Support (P2P)
    • Pricing
    • SLA
    • Glossary
Powered by GitBook
On this page
  • Creating a custom DescriptorProvider
  • Creating a custom Binding

Was this helpful?

Export as PDF
  1. coherence SDK for Unity
  2. Networking State Changes

Creating your own syncable member

Extending what can be synced from the Configure window

This is an advanced topic that aims to bring access to coherence's internals to the end user.

The Configure window lists all variables and methods that can be synced for the selected Prefab. Each selected element in the list is stored in the Prefab as a Binding with an associated Descriptor, which holds information about how to access that data.

By default, coherence uses reflection to gather public fields, properties and methods from each of the Prefab's components. You can specify exactly what to list in the Configure window for a given component by implementing a custom DescriptorProvider. This allows you to sync custom component data over the network.

Take this player inventory for example:

using UnityEngine;

public class Inventory : MonoBehaviour
{
    [System.Serializable]
    public class Item
    {
        public int id;
        public string name;
        public int durability;
    }

    public Item[] items = new Item[]
    {
        new Item {id = 0, name = "Shield", durability = 80},
        new Item {id = 1, name = "Stick", durability = 50},
        new Item {id = 2, name = "Stone", durability = 100},
    };

    public Item GetItem(int id)
    {
        foreach (var item in items)
        {
            if (item.id == id)
            {
                return item;
            }
        }

        return default;
    }
}

Since the inventory items are not immediately accessible as fields or properties, they are not listed in the Configure window. In order to expose the inventory items so they can be synced across the network, we need to implement a custom DescriptorProvider.

Creating a custom DescriptorProvider

The main job of the DescriptorProvider is to provide the list of Descriptors that you want to show up in the Configure window. You can instantiate new Descriptors using this constructor:

public Descriptor(string name, Type ownerType, Type bindingType, bool required=false)
  • name: identifying name for this Descriptor.

  • ownerType: type of the MonoBehaviour that this Descriptor is for.

  • bindingType: type of the ValueBinding class that will be instantiated and serialized in CoherenceSync, when selecting this Descriptor in the Configure window.

  • required: if true, every network Prefab that uses a MonoBehaviour of ownerType will always have this Binding active.

If you need to serialize additional data with your Descriptor, you can inherit from the Descriptor class or assign a Serializable object to Descriptor.CustomData.

Here is an example InventoryDescriptorProvider that returns a Descriptor for each of the inventory items:

using System.Collections.Generic;
using Coherence.Toolkit;
using Coherence.Toolkit.Bindings;

[DescriptorProvider(typeof(Inventory))]
public class InventoryDescriptorProvider : DescriptorProvider
{
    public override List<Descriptor> Fetch()
    {
        // Call base.Fetch to include public fields, properties and methods
        var descriptors = base.Fetch();

        var inventory = Component as Inventory;

        foreach (var item in inventory.items)
        {
            var inventoryDescriptor = new Descriptor(name: item.name, ownerType: typeof(Inventory), bindingType: typeof(InventoryBinding));
            inventoryDescriptor.CustomData = item.id;
            descriptors.Add(inventoryDescriptor);
        }

        return descriptors;
    }
}

To specify how to read and write data to the Inventory component, we also need a custom binding implementation.

Creating a custom Binding

A Descriptor must specify through the bindingType which type of ValueBinding it is going to instantiate when synced in a CoherenceSync. In our example, we need an InventoryBinding to specify how to set and get the values from the Inventory. To sync the durability property of the inventory item, we should extend the IntBinding class which provides functionality for syncing int values.

using Coherence.Toolkit.Bindings;
using Coherence.Toolkit.Bindings.ValueBindings;
using UnityEngine;

public class InventoryBinding : IntBinding
{
    public override string BakedSyncScriptGetter => "GetItem(ItemId).durability";
    public override string BakedSyncScriptSetter => "GetItem(ItemId).durability = @";

    // Required constructor signatures
    public InventoryBinding(Descriptor descriptor, Component unityComponent) : base(descriptor, unityComponent) { }
    public InventoryBinding() { }

    public int ItemId => (int)descriptor.CustomData;

    public override int Value
    {
        get => ((Inventory) unityComponent).GetItem(ItemId).durability;
        set => ((Inventory) unityComponent).GetItem(ItemId).durability = value;
    }
}

We are now ready to sync the inventory items on the Prefabs.

Last updated 1 year ago

Was this helpful?

For the full list of supported binding types, see .

Supported types in Commands and Bindings
The Inventory component does not expose the inventory items by default.
The Inventory items can now be synced across the network.