Spawning & Pooling
GONet provides network-aware instantiation with zero-latency spawning, adaptive object pooling, and clean despawn handling across all connected clients.
Network Spawning
Use GONetMain.Instantiate() as a drop-in replacement for UnityEngine.Object.Instantiate(). It automatically assigns a GONetId and replicates the object to all clients.
// Spawn a networked object
var projectile = GONetMain.Instantiate(
projectilePrefab,
firePoint.position,
firePoint.rotation
);
// Despawn a networked object
GONetMain.DespawnGONetParticipant(projectile.GetComponent<GONetParticipant>());- --The prefab must have a
GONetParticipantcomponent attached. - --The prefab must be in a
Resourcesfolder (or loaded via Addressables).
Zero-Latency Spawning
Normally, a client must request a GONetId from the server before it can spawn an object. This round-trip adds 50-150ms of delay before the object appears. GONet solves this with the GONetId Batch System.
How it works
- Client connects to the server.
- Server sends a batch of 200 GONetIds (configurable).
- Client can spawn objects instantly using pre-allocated IDs.
- At 50% consumption, the next batch is requested in the background.
- If the batch runs out, "limbo mode" handles it gracefully.
Configuring Batches
These settings are available in the GONetGlobal inspector.
| Setting | Description |
|---|---|
client_GONetIdBatchSize | IDs per batch (100-1000, default 200) |
client_GONetIdBatchLimboMode | Behavior when batch is exhausted (see below) |
Limbo Mode Options
ReturnFailure
Spawn returns null. The safe default -- your code is responsible for handling the null case.
InstantiateInLimborecommended
Creates a "ghost" object that becomes real when the next batch arrives. Provides the most seamless player experience.
BlockUntilBatchArrives
Waits synchronously for the server to send a new batch. Not recommended -- causes frame stutter.
QueueRequestWithCallback
Queues the spawn request and invokes a callback when the next batch arrives. Non-blocking and avoids frame stutter. Good for fire-and-forget spawns where a small delay is acceptable.
Object PoolingGONet Legendary
Object pooling is a GONet Legendary feature (v1.6+). The API below shows the intended design. Until then, you can use standard Unity object pooling patterns alongside GONet spawning.
GONet will include a built-in adaptive pooling system. Implement IGONetPoolResettable on your networked components to opt in.
public class Projectile : GONetParticipantCompanionBehaviour, IGONetPoolResettable
{
private Rigidbody rb;
void IGONetPoolResettable.ResetForPoolBorrow()
{
// Called when object is borrowed from pool
rb = GetComponent<Rigidbody>();
rb.velocity = Vector3.zero;
gameObject.SetActive(true);
}
void IGONetPoolResettable.ResetForPoolReturn()
{
// Called when object is returned to pool
gameObject.SetActive(false);
}
}Adaptive Pool ScalingGONet Legendary
GONet will automatically grow pools based on demand. GONetAdaptivePoolScaler will monitor utilization and adjust pool sizes to prevent allocation spikes during gameplay.
Monitor pool utilization at runtime with GONetMain.GetMonitor().
Destroying Networked Objects
// Network-safe destroy
GONetMain.DespawnGONetParticipant(participant);
// Or using the convenience method
GONetMain.DestroyImmediate(gameObject);- --Both methods handle cleanup on all clients.
- --If using pooling, objects are returned to the pool instead of destroyed.
Best Practices
- --Use
InstantiateInLimbofor the smoothest player experience. - --Pool frequently spawned and despawned objects (projectiles, effects, pickups) to avoid GC pressure.
- --Keep prefabs in
Resourcesor use Addressables for on-demand loading. - --Monitor pool utilization in development builds to tune pool sizes before shipping.