Class ObjectSpawner
Manages spawning and respawning of networked objects in the game world. Supports various spawn types, respawn conditions, and object pooling.
[RequireComponent(typeof(NetworkObject))]
public class ObjectSpawner : NetworkBehaviour
- Inheritance
-
ObjectComponentBehaviourMonoBehaviourNetworkBehaviourObjectSpawner
- Inherited Members
-
NetworkBehaviour.IsSpawnedNetworkBehaviour.ComponentIndexNetworkBehaviour.NetworkObjectNetworkBehaviour.MAXIMUM_NETWORKBEHAVIOURSNetworkBehaviour.UNSET_NETWORKBEHAVIOUR_IDNetworkBehaviour.ToString()NetworkBehaviour.Reset()NetworkBehaviour.OnValidate()NetworkBehaviour.IsBehaviourReconcilingNetworkBehaviour.ClearReplicateCache()NetworkBehaviour.CreateReconcile()NetworkBehaviour.Reconcile_Reader<T>(PooledReader, ref T)NetworkBehaviour.OnStartServerCalledNetworkBehaviour.OnStartClientCalledNetworkBehaviour.WritePayload(NetworkConnection, Writer)NetworkBehaviour.ReadPayload(NetworkConnection, Reader)NetworkBehaviour.OnStartServer()NetworkBehaviour.OnStopServer()NetworkBehaviour.OnOwnershipServer(NetworkConnection)NetworkBehaviour.OnSpawnServer(NetworkConnection)NetworkBehaviour.OnDespawnServer(NetworkConnection)NetworkBehaviour.OnStartClient()NetworkBehaviour.OnStopClient()NetworkBehaviour.OnOwnershipClient(NetworkConnection)NetworkBehaviour.ClearBuffedRpcs()NetworkBehaviour.ExcludeOwnerFromUnbufferedObserversRpcsNetworkBehaviour.IsClientOnlyNetworkBehaviour.IsServerOnlyNetworkBehaviour.IsHostNetworkBehaviour.IsClientNetworkBehaviour.IsServerNetworkBehaviour.IsDeinitializingNetworkBehaviour.NetworkManagerNetworkBehaviour.ServerManagerNetworkBehaviour.ClientManagerNetworkBehaviour.ObserverManagerNetworkBehaviour.TransportManagerNetworkBehaviour.TimeManagerNetworkBehaviour.SceneManagerNetworkBehaviour.PredictionManagerNetworkBehaviour.RollbackManagerNetworkBehaviour.NetworkObserverNetworkBehaviour.IsClientInitializedNetworkBehaviour.IsClientStartedNetworkBehaviour.IsClientOnlyInitializedNetworkBehaviour.IsClientOnlyStartedNetworkBehaviour.IsServerInitializedNetworkBehaviour.IsServerStartedNetworkBehaviour.IsServerOnlyInitializedNetworkBehaviour.IsServerOnlyStartedNetworkBehaviour.IsHostInitializedNetworkBehaviour.IsHostStartedNetworkBehaviour.IsOfflineNetworkBehaviour.IsNetworkedNetworkBehaviour.GetIsNetworked()NetworkBehaviour.IsManagerReconcilingNetworkBehaviour.ObserversNetworkBehaviour.IsOwnerNetworkBehaviour.IsControllerNetworkBehaviour.HasAuthorityNetworkBehaviour.OwnerNetworkBehaviour.OwnerIdNetworkBehaviour.ObjectIdNetworkBehaviour.LocalConnectionNetworkBehaviour.OwnerMatches(NetworkConnection)NetworkBehaviour.Despawn(GameObject, DespawnType?)NetworkBehaviour.Despawn(NetworkObject, DespawnType?)NetworkBehaviour.Despawn(DespawnType?)NetworkBehaviour.Spawn(GameObject, NetworkConnection, Scene)NetworkBehaviour.Spawn(NetworkObject, NetworkConnection, Scene)NetworkBehaviour.RemoveOwnership()NetworkBehaviour.GiveOwnership(NetworkConnection)NetworkBehaviour.GetInstance<T>()NetworkBehaviour.TryRegisterInstance<T>(T)NetworkBehaviour.UnregisterInstance<T>()NetworkBehaviour.CanLog(LoggingType)MonoBehaviour.IsInvoking()MonoBehaviour.CancelInvoke()MonoBehaviour.StopCoroutine(Coroutine)MonoBehaviour.StopAllCoroutines()MonoBehaviour.destroyCancellationTokenMonoBehaviour.useGUILayoutMonoBehaviour.didStartMonoBehaviour.didAwakeMonoBehaviour.runInEditModeBehaviour.enabledBehaviour.isActiveAndEnabledComponent.GetComponent<T>()Component.TryGetComponent<T>(out T)Component.GetComponentInChildren<T>()Component.GetComponentsInChildren<T>()Component.GetComponentInParent<T>()Component.GetComponentsInParent<T>()Component.GetComponents<T>()Component.GetComponentIndex()Component.CompareTag(TagHandle)Component.transformComponent.transformHandleComponent.gameObjectComponent.tagObject.GetEntityId()Object.GetInstanceID()Object.GetHashCode()Object.InstantiateAsync<T>(T)Object.InstantiateAsync<T>(T, Transform)Object.InstantiateAsync<T>(T, Vector3, Quaternion)Object.InstantiateAsync<T>(T, Transform, Vector3, Quaternion)Object.Instantiate(Object, Vector3, Quaternion)Object.Instantiate(Object, Vector3, Quaternion, Transform)Object.Instantiate(Object)Object.Instantiate(Object, Scene)Object.Instantiate<T>(T, InstantiateParameters)Object.Instantiate<T>(T, Vector3, Quaternion, InstantiateParameters)Object.Instantiate(Object, Transform)Object.Instantiate<T>(T)Object.Instantiate<T>(T, Vector3, Quaternion)Object.Instantiate<T>(T, Vector3, Quaternion, Transform)Object.Instantiate<T>(T, Transform)Object.Destroy(Object)Object.DestroyImmediate(Object)Object.DontDestroyOnLoad(Object)Object.DestroyObject(Object)Object.FindObjectsOfType<T>()Object.FindObjectsByType<T>(FindObjectsSortMode)Object.FindObjectsByType<T>(FindObjectsInactive, FindObjectsSortMode)Object.FindObjectOfType<T>()Object.FindFirstObjectByType<T>()Object.FindAnyObjectByType<T>()Object.FindFirstObjectByType<T>(FindObjectsInactive)Object.FindAnyObjectByType<T>(FindObjectsInactive)Object.FindObjectsByType<T>()Object.FindObjectsByType<T>(FindObjectsInactive)Object.nameObject.hideFlags
Fields
BoundingBoxExtents
The extents (half-size) of the bounding box, calculated from BoundingBoxSize.
[HideInInspector]
public Vector3 BoundingBoxExtents
Field Value
- Vector3
BoundingBoxSize
The size of the bounding box used for random spawn position selection.
public Vector3 BoundingBoxSize
Field Value
- Vector3
GizmoColor
The color used to draw the spawner's gizmo in the editor.
public Color GizmoColor
Field Value
- Color
InitialRespawnTime
The initial respawn time (in seconds) for spawned objects.
public float InitialRespawnTime
Field Value
InitialSpawnCount
The number of objects to spawn initially when the spawner starts.
public int InitialSpawnCount
Field Value
IsCacheDirty
Flag to track if the spawn chance cache needs updating.
[HideInInspector]
public bool IsCacheDirty
Field Value
MaxSpawnCount
The maximum number of objects that can be spawned by this spawner.
[Tooltip("The maximum number of objects that can be spawned by this spawner.")]
public int MaxSpawnCount
Field Value
OrConditions
If any of these conditions return true, the object will respawn. This list is checked first (logical OR).
public List<BaseRespawnCondition> OrConditions
Field Value
PrewarmHeadroom
Extra instances reserved beyond MaxSpawnCount.
[Tooltip("Extra pooled instances beyond MaxSpawnCount, as slack for prefabs shared between spawners.")]
[Min(0)]
public int PrewarmHeadroom
Field Value
Remarks
Slack, not a requirement. A corpse holds its spawner slot for the whole of its decay — Despawn(ISpawnable) is what frees the slot and starts the respawn clock, and a corpse does not reach it until the decay timer expires — so this spawner can never have more than MaxSpawnCount live instances and the reservation alone would do.
The headroom is kept because the pool is shared: ObjectSpawnerPool de-duplicates reservations across every spawner using the same prefab, taking the largest single demand rather than the sum, so a prefab used by many spawners at once genuinely can need more instances than any one spawner reserved. This covers that without making the reservation quadratic.
PrewarmPool
When true, every prefab this spawner can produce is instantiated into the object pool at scene start, up to MaxSpawnCount each.
[Header("Pooling")]
[Tooltip("Instantiate this spawner's prefabs into the pool at scene start for a fixed memory footprint.")]
public bool PrewarmPool
Field Value
Remarks
This is what makes a map's memory footprint deterministic. Without it the pool fills lazily — the first NPC of each kind is instantiated the moment a player walks into range — so a freshly loaded map hitches as it is explored and only reaches its true heap size once every spawner has fired at least once. Neither behaviour can be planned against.
Turn it off for spawners whose prefabs are large and rarely used, where paying the cost on demand is preferable to paying it always.
RandomRespawnTime
If true, a random respawn time is selected within the minimum and maximum range. Otherwise, the initial respawn time is used.
[Tooltip("If true a random number will be selected within the minimum and maximum range provided. Otherwise the maximum respawn time will be used.")]
public bool RandomRespawnTime
Field Value
RandomSpawnPosition
If true, a random spawn position is picked inside the bounding box using the current position as the center.
[Tooltip("If true a random spawn position will be picked inside of the bounding box using the current position as the center.")]
public bool RandomSpawnPosition
Field Value
RespawnCheckIntervalMaximum
Longest delay between respawn checks, in seconds.
[Tooltip("Longest delay between respawn checks, in seconds. Each check picks a fresh random delay in this range so spawners do not all poll on the same frame.")]
public float RespawnCheckIntervalMaximum
Field Value
RespawnCheckIntervalMinimum
Shortest delay between respawn checks, in seconds.
[Tooltip("Shortest delay between respawn checks, in seconds. Respawn deadlines are wall-clock, so this only sets how soon after a deadline the object appears - it does not change respawn timing itself.")]
public float RespawnCheckIntervalMinimum
Field Value
SchedulerIndex
This spawner's position in ObjectSpawnerScheduler's active list, or NotActive when it has no work outstanding.
[NonSerialized]
public int SchedulerIndex
Field Value
Remarks
Stored here so the scheduler can drop a spawner without searching for it. Owned by the scheduler; nothing else should write it.
SpawnType
The type of spawn selection (Linear, Random, Weighted).
public ObjectSpawnType SpawnType
Field Value
SpawnableRespawnTimers
List of respawn timers for each spawnable object.
public List<DateTime> SpawnableRespawnTimers
Field Value
Spawnables
The list of spawnable settings used to configure each spawnable object. Supports polymorphic subclasses via UnityEngine.SerializeReference for type-specific data injection.
[SerializeReference]
public List<SpawnableSettings> Spawnables
Field Value
Spawned
Dictionary of currently spawned objects, keyed by their unique ID.
public Dictionary<long, ISpawnable> Spawned
Field Value
SphereRadius
SphereCast radius used for spawning objects in the world.
[Tooltip("SphereCast radius used for spawning objects in the world.")]
public float SphereRadius
Field Value
Transform
Cached reference to the spawner's transform.
[HideInInspector]
public Transform Transform
Field Value
- Transform
TrueConditions
All conditions must return true for the object to respawn. This list is checked second (logical AND).
public List<BaseRespawnCondition> TrueConditions
Field Value
UniqueSpawnables
When true, at most one live instance of each entry in Spawnables may exist at a time.
[Tooltip("Allow at most one live instance of each spawnable. Off by default. Turn on when every entry is a distinct individual that should never be duplicated.")]
public bool UniqueSpawnables
Field Value
Remarks
Off by default, because the normal case is a spawner filling a zone with several of the same creature. Turn it on where each entry names a distinct individual — a zone listing several named NPCs would otherwise draw the same one repeatedly and stand two copies of it side by side, since the spawn index is chosen without regard to what is already alive.
This caps each entry at one, not the spawner: MaxSpawnCount still governs the total, so with this on the effective ceiling is the smaller of MaxSpawnCount and the number of assigned spawnables.
Methods
Despawn(ISpawnable)
Despawns the specified spawnable object, schedules its respawn, and removes it from the spawned dictionary.
public void Despawn(ISpawnable spawnable)
Parameters
spawnableISpawnableThe spawnable object to despawn.
GetSpawnIndex()
Gets the index of the next spawnable to use, based on the configured spawn type.
public int GetSpawnIndex()
Returns
- int
The index of the selected spawnable.
HasRespawnWork()
Whether this spawner has anything left to respawn.
public bool HasRespawnWork()
Returns
- bool
True when a respawn is outstanding.
Remarks
Decides membership of ObjectSpawnerScheduler's active list, and so decides whether this spawner costs anything at all. A spawner at its cap or with no pending timers is not walked, which is the whole point: the cost of respawning scales with how much of the world is in motion rather than with how much of it exists.
OnStartNetwork()
Called when the network starts. Initializes spawner, validates spawnables, and spawns initial objects.
public override void OnStartNetwork()
OnStopNetwork()
Called when the network stops. Drops this spawner from the respawn schedule.
public override void OnStopNetwork()
Remarks
Without this a spawner in an unloaded scene stays queued and is woken against a destroyed object. The scheduler tolerates that, but leaving it to tolerate it means the heap carries entries for scenes that no longer exist.
SpawnObject()
Spawns a new object in the world using the selected spawnable settings and position logic.
public void SpawnObject()
TryRespawn()
Attempts to respawn objects if their timers have elapsed and respawn conditions are met.
public void TryRespawn()
Remarks
Public so anything holding a spawner can force an immediate attempt rather than waiting for its scheduled wake. The scheduler reaches the same work through RunScheduledRespawn(DateTime, float).