LogoLogo
HomeOnline DashboardAPIDiscordForums
SDK 1.6
SDK 1.6
  • Welcome
  • Overview
    • Features
    • Roadmap
  • Getting started
    • Get the Unity SDK
    • Setup a project
      • 1. Scene setup
      • 2. Prefab setup
      • 3. Test your game locally
        • Local testing using builds
        • Local testing via Unity's Multiplayer Play Mode
        • Local testing via ParrelSync
      • 4. Test in the cloud
        • Deploy a Replication Server
        • Share builds
    • How to... ?
    • Single-player to multiplayer
    • Video tutorials
    • Samples and tutorials
      • Package samples
      • Sample Connection UIs
      • First Steps tutorial
        • 1. Basic syncing
          • 1.1 Animation parameters
          • 1.2 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
      • Beginner's guide to networking
    • Troubleshooting
  • Manual
    • Unity Components
      • CoherenceSync
      • CoherenceBridge
      • CoherenceLiveQuery
      • CoherenceTagQuery
      • CoherenceGlobalQuery
      • CoherenceInput
      • CoherenceNode
      • PrefabSyncGroup
      • Order of execution
    • Networking state changes
      • Instantiate and Destroy Objects
      • Supported types
      • Messaging with Commands
      • Syncing child GameObjects
      • Animation
      • CoherenceSync references
      • [Sync] and [Command] Attributes
      • [OnValueSynced] Attribute
      • Creating your own syncable member
      • Custom Component Actions
      • Rigid Bodies
      • Interpolation
    • Authority
      • Authority transfer
      • Server-authoritative setup
    • Lifetime
      • Persistence
      • Uniqueness
      • Example: A global counter
    • Parenting network entities
      • Direct children CoherenceSyncs
      • Deeply-nested CoherenceSyncs
      • Nesting Prefabs at Edit time
    • Asset management
      • Instantiating from CoherenceSyncConfig
      • Instantiate via
      • Load via
    • Scene management
    • Multiple Connections within a Game Instance
    • Baking (code generation)
      • Conditional compilation
    • Replication Server
      • Rooms and Worlds
      • Replication Server API
    • Simulators (Servers)
      • Scripting: Client vs Simulator
      • Run local Simulators
      • World Simulators
      • Room Simulators
      • Simulator slugs
      • Build and Deploy
      • Command-line arguments
    • Client Connections
    • Optimization
      • Areas of Interest
      • Level of Detail (LOD)
      • Profiling
      • Simulation Frequency
    • Project Settings
    • Advanced topics
      • Big worlds
        • World Origin Shifting
        • Load balancing
      • Competitive games
        • Simulation Frame
        • Determinism, Prediction and Rollback
      • Team workflows
        • Version Control integration
        • Continuous Integration
      • Schema explained
        • Specification
        • Field settings
        • Archetypes
      • Code stripping
      • Replication Server CLI
      • Single-player gameplay
    • Scripting API
  • Hosting
    • Choosing where to host
    • coherence Cloud
      • Online Dashboard
      • Manage Worlds
      • Configure Rooms
      • Player Accounts
      • Game Services
        • Lobbies
        • Cloud Storage
        • Key-Value Store (Legacy)
      • APIs
        • Worlds
        • Rooms
        • Lobbies
        • Cloud Storage
        • Key-Value Store (Legacy)
    • Peer-to-peer
      • Implementing Client hosting
  • Support
    • Release notes
    • Glossary
    • Unreal Engine support
    • WebGL support
    • ECS / DOTS support
    • Known issues
    • Upgrade guide
      • Upgrade 1.5 -> 1.6
      • Upgrade 1.4 -> 1.5
      • Upgrade 1.3 -> 1.4
      • Upgrade 1.2 -> 1.3
      • Upgrade 1.1 -> 1.2
      • Upgrade 1.0 -> 1.1
      • Upgrade 0.10 -> 1.0
      • Upgrade 0.9 -> 0.10
    • Credit cost & pricing
    • Report a bug
Powered by GitBook
On this page
  • How do I specify a Prefab to spawn for the player?
  • Instantiating entities
  • Who gets authority?
  • Instantiate objects for other clients
  • Destroying entities
  • Destroying other player's entities
  • Customise instantiation and destruction
  • Object pooling

Was this helpful?

Export as PDF
  1. Manual
  2. Networking state changes

Instantiate and Destroy Objects

Was this helpful?

coherence makes it easy to instantiate networked objects. If you instantiate a while the game is running, it automatically instantiates on all connected clients. You don't need to do anything else to make it happen.

However some rules apply, so read on to understand more about the process.

How do I specify a Prefab to spawn for the player?

It is important to understand that coherence has no concept of a "player Prefab" that maps 1:1 with each Client. Clients can control only one network entity, multiple, or none at all.

Clients can also trade authority over them at runtime. For example, a Client might initially have authority over a character, which can then move to another Client during gameplay.

It's up to you to decide what constitutes a "player Prefab": you can instantiate one before connecting, right after connection, or at any point during the simulation. You can even just leave it in the scene, and let each player bring a copy of that into the simulation (in this case, make sure the Prefab is not set to be !).

Finally, if you come from other networking frameworks, you might expect a player Prefab to be be instantiated by the network manager (in coherence, the ), but that is not the case. Like all other network entities, it can be instantiated by any script.

Identifying Clients

You do have the ability to assign a Prefab to each client: the . This lives and dies with the client's connection, and you can use it to hold important data related to that Client. You can assign it in the Inspector of the .

ClientConnection Prefabs are optional.

Instantiating entities

You can instantiate a networked Prefab in the following ways:

  • Use GameObject.Instantiate(), and provide a reference to the Prefab:

GameObject newGameObject = Instantiate(prefab);
  • Simply include the Prefab in a scene.

  • (Editor only, for testing) Drag the Prefab from the Project window to the scene or to the Hierarchy while the game is running.

In all of these cases, the Prefab will be immediately instantiated on all other connected clients and Simulators.

Who gets authority?

Instantiate objects for other clients

You cannot directly instantiate an entity owned by another Client. The Client that instantiates a Prefab automatically has authority over it.

However, you can transfer authority immediately after instantiation. In code:

// Instantiates a Prefab and immediately gives authority away
public void SpawnAndTransfer(GameObject prefab, ClientID recipientID)
{
        GameObject newGameObject = Instantiate(prefab);
        newGameObject.GetComponent<CoherenceSync>().TransferAuthority(recipientID);
}

This is a perfectly valid strategy to have a Simulator spawn player characters for connected Clients.

Destroying entities

To destroy a networked Prefab, simply invoke GameObject.Destroy() on it. coherence will automatically destroy all remote copies.

Keep in mind is that only whoever has State authority over it can destroy an entity. If someone else does it, they will get a warning in the console.

Destroying other player's entities

Clients cannot directly destroy entities they don't have authority over. Instead, you may:

private void DestroyNetworkEntity(GameObject objectToRemove)
{
    CoherenceSync sync = objectToRemove.GetComponent<CoherenceSync>();
    
    if (sync.HasStateAuthority)
    {
        // If we have authority, no need to send a command
        Destroy(objectToRemove);
    }
    else
    {
        // Change MyBehaviour here to whatever type will receive the Command
        sync.SendCommand<MyBehaviour>(nameof(MyBehaviour.RemoveObject),
                                            MessageTarget.AuthorityOnly);
    }
}
// The command invoked on the receiving end
[Command]
public void RemoveObject()
{
    Destroy(this.gameObject);
}
private void RequestDestroy(GameObject objectToRemove)
{
    CoherenceSync sync = objectToRemove.GetComponent<CoherenceSync>();
    
    if (sync.HasStateAuthority)
    {
        Destroy(objectToRemove);
    }
    else
    {
        // Listen to authority transfer
        sync.OnStateAuthority.AddListener(() => Destroy(objectToRemove));
        
        sync.RequestAuthority(AuthorityType.Full);
    }
}

Note that we're assuming that the request above always succeeds, and we're not implementing any approval/denial code for the sake of simplicity.

Customise instantiation and destruction

In coherence, you can take full control of how network entities are instantiated.

Object pooling

We natively support object pooling, so that newly requested entities don't just get created from scratch, but they are taken from a pre-existing pool.

How to use object pooling

In the CoherenceSync component inspector, you will find an option called Instantiate Via.

Select the option called Pool, and define the initial and max size of the pool:

When the game starts, coherence will automatically create a pool of disabled instances of this Prefab in the DontDestroyOnLoad scene. It will then activate these for new remote entities that use this Prefab that other clients created.

Use your pre-existing object pooling system

Just ensure to include a CoherenceSync component on the Prefab, and that netcode is correctly.

Whoever instantiates a Prefab gets full over it. All other clients will see it as remote.

The value of the Simulate In property on the CoherenceSync can modify this behaviour. Read more about .

(to get other clients' IDs you need to have enabled)

Send a to ask the owner to destroy it. In code:

Take authority over the entity first, then destroy it locally. This is slightly slower as it implies a full roundtrip (request > response > destruction), but it's a viable option if the requester needs to verify whether the entity can be destroyed at all. You can implement the conditions under which the other client will . In code:

A typical use for custom instantiation is streaming assets in with the , which coherence is fully integrated with. Another typical use case is .

To use custom instantiation you can't just hard reference the Prefab and invoke Instantiate() or Destroy() as described above. Instead, you have to to let the chosen instantiator script take over and perform custom operations.

If you want to take from the same pooling system to instantiate your own local/authoritative entities, you can do so by using the corresponding to your Prefab. If you reference this asset, you will be able to : these methods will use the underlying pool implementation to do so.

When remote entities are removed or go out of a , they will be automatically deactivated and move back into the pool.

If you already have a pooling system in place (even a third-party asset!) and you would like remote objects to leverage it, you can hook your own pool into a custom instantiator using the INetworkObjectInstantiator interface. This is described in the .

baked
authority
authority models
ClientConnections
Network Command
use its CoherenceSyncConfig
LiveQuery
Addressables package
object pooling
unique
CoherenceBridge
CoherenceBridge
instantiate and destroy entities by using its API
CoherenceSyncConfig asset
ClientConnection Prefab
approve or deny the request
A CoherenceSync for which the Pool instantiator has been selected
Instantiate Via page