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
  • Our use case
  • Prefab setup
  • Spawning a new log
  • Burning a log
  • Cleaning up

Was this helpful?

Export as PDF
  1. Learning coherence
  2. Campfire project

Leveraging object pooling

Last updated 1 year ago

Was this helpful?

Topics covered

| |

Network entities need to be created and removed all the time. This can be due to entities getting in and out of a LiveQuery, or simply because gameplay requires so. If that is the case, we can leverage coherence's object pooling system in order to avoid costly calls to Instantiate and Destroy, which are famously expensive operations in Unity.

Our use case

In this project we use pooling for one very clear use case: the tree logs that get spawned when chopping down a tree.

This was a natural choice as players will be chopping trees all the time, but we can also assume that they will burn the logs on the fire almost as often. So by pre-allocating a pool of around 10 logs, we should be covered in most cases.

Prefab setup

To set up the log to behave like this, all we did was to set that option on the log's own CoherenceSync inspector.

A pool configured like this means that coherence will pre-spawn 10 instances of the Prefab at the beginning of the game.

However if we were to need more, we could request more instances and they would be created and added to the pool. The game can even go above 20. If that were to happen, any instance released beyond 20 wouldn't just be returned to the pool, but would be destroyed.

In other words, 10 and 20 represent the lower and upper limit for the amount of memory we are reserving for the logs alone in our game. We are considering anything above 20 as a temporary exception.

When we press Play, coherence instantiates these 10 logs, deactivate them, and put the pool in the DontDestroyOnLoad scene:

Because they are inactive, their CoherenceSync components are not syncing any value.

Spawning a new log

To spawn a new log we only need to call one line of code. However, we don't provide a reference to a regular Prefab like we would with Instantiate. We instead leverage the CoherenceSyncConfig object that represents the log.

This CoherenceSyncConfig contains all the info that coherence needs to handle this particular Prefab over the network. If we inspect it, we will notice that it contains in fact how the object is loaded (Load via) and how it's instantiated (Instantiate via).

You can notice how this is the same info we saw while configuring the CoherenceSync before.

Now that we have a reference to it, we can spawn the log with one line of code. In the ChoppableTree script, we do something like:

CoherenceSync newLog =
    logSyncConfig.GetInstance(transform.position + [...], Quaternion.identity);

This line looks remarkably similar to Unity's own Instantiate in its syntax. The difference is that it gives us back a reference to the CoherenceSync attached to the log instance that will be enabled. From this, we can do all sorts of setup operations by just fetching other components with GetComponent, to prepare the instance.

Burning a log

When we are done with it (in this case, when it's thrown into the campfire), we can dispose of it:

_sync.ReleaseInstance();

(this line is in the Burnable.cs class, inside the GetBurned() method)

The instance is then automatically returned into the pool, and disabled.

Cleaning up

When taking an instance out of the pool or when returning it, coherence doesn't automatically do any particular clean up to its state.

As such, when we reuse a pool instance, it is good practice to think of what values should be reset that might have been messed up by previous usage. We should think about what happens during gameplay, and use OnEnable / OnDisable as needed to ensure that disabled instances are put in a state that makes them ready to be used again.

For this project, since an object can be burned while being carried, we do some cleaning in the OnDisable of the Grabbable.cs class to prepare the wood logs for another round, like so:

private void OnDisable()
{
    isBeingCarried = false;
    _rigidbody.isKinematic = false;
    _collider.enabled = true;
    
    // ... in addition to removing any listener set in OnEnable
}

Check the Log prefab in Prefabs/Interactive/Burnable/:

This Sync Config can be found in the coherence/ folder, and is a sub-object of another ScriptableObject: the CoherenceSyncConfigRegistry.

📁
📁
CoherenceSyncConfigRegistry
CoherenceSyncConfig
Object pooling
A player just chopped a tree, and a log has been spawned
The Log Prefab is set to instantiate from a pool
The object pool for logs, ready to use
The ChopTree script referencing the log's CoherenceSyncConfig
The Log's CoherenceSyncConfig