Instantiator
Instantiator spawns prefabs so that every client in the session sees them. It
is how a multiplayer game creates one avatar per player, or a ball that everyone
can see.
Add it to a scene object, list the prefabs it is allowed to spawn, then either
declare a spawn with registerSpawn() or call instantiate() directly. For the
common case of "one prefab, spawned for as long as this component lives," use
Network Spawner instead, which wraps this component.
Component Inputs
| Name | Type | Description |
|---|---|---|
| Network Id | Hierarchy, Custom Id, or Object Id | When the Instantiator is created dynamically, use Custom Id or Hierarchy so it is synchronized across clients. Use Object Id when the Instantiator sits in the scene hierarchy statically. Defaults to Object Id. |
| Custom Network Id | string | Shown when Network Id is Custom Id. Must be the same string on every client. Defaults to enter_global_unique_id. |
| Prefabs | ObjectPrefab[] | The prefabs this Instantiator may spawn. A prefab not in this list is rejected. |
| Spawner Owns Object | boolean | If enabled, the Instantiator owns what it spawns. Defaults to false. |
| Spawn As Children | boolean | If enabled, instances are parented rather than created at the scene root. Defaults to false. |
| Spawn Under Parent | SceneObject | Shown when Spawn As Children is enabled. The parent for new instances. |
Component API
| Name (signature) | Description |
|---|---|
registerSpawn(declaration: SpawnDeclaration): Spawn | Declares a spawn tied to a scope. Returns a Spawn handle. The preferred entry point. |
instantiate(prefab: ObjectPrefab, options?: InstantiationOptions | InstantiationOptionsObj): Promise<NetworkRootInfo> | Spawns a prefab immediately. |
destroyInstances() | Destroys every instance this Instantiator created. |
destroyOwnedInstances() | Destroys only the instances the local client owns. |
trySpawnFromStore(storeInfo: StoreInfo) | Spawns from an existing store, used when catching up as a late joiner. |
isReady(): boolean | Whether the Instantiator is ready to spawn. |
waitForReady(): Promise<void> | Resolves once ready. |
getSyncEntity(): SyncEntity | The Sync Entity backing this Instantiator. |
SpawnDeclaration
| Field | Type | Description |
|---|---|---|
prefab | ObjectPrefab | Required. Must be in the Prefabs list. |
scope | BaseScriptComponent or SceneObject | Required. The spawn lives as long as this scope does. |
customNetworkId | string | Required for a host-managed spawn, and must be globally unique. |
ownership | Ownership | Owned, Unowned, or HostOwned. |
persistence | Persistence | Ephemeral, Owner, Session, or Persist. |
worldPosition / worldRotation / worldScale | vec3 / quat / vec3 | Spawn transform in world space. |
localPosition / localRotation / localScale | vec3 / quat / vec3 | Spawn transform in local space. |
localInstantiationContext | unknown | Arbitrary local-only data passed through to the instance. |
registerSpawn() validates and throws on: a missing prefab, a destroyed scope,
a prefab that is not in the Prefabs list, a duplicate customNetworkId, a
per-client spawn declared as anything other than Owned, and a host-managed
spawn declared as Owned.
Spawn
The handle returned by registerSpawn().
| Name | Description |
|---|---|
instance | The spawned NetworkRootInfo, or null before it exists. |
isHostManaged | Whether this is a single host-managed instance. |
hasEnded | Whether the spawn has ended. |
customNetworkId | The id passed at registration, or null. |
onSpawned | Event, called with the NetworkRootInfo. |
onDespawned | Event, called with no arguments. |
InstantiationOptionsObj
Passed to instantiate(). Fields: persistence, ownership, worldPosition,
worldRotation, worldScale, localPosition, localRotation, localScale,
onError, overrideNetworkId, customDataStore, localInstantiationContext.
Usage
import { Instantiator } from 'ConnectedFramework.lspkg/Components/Instantiator';
import { Ownership } from 'ConnectedFramework.lspkg/Core/StoreTypes';
@component
export class SpawnAvatar extends BaseScriptComponent {
@input
instantiator!: Instantiator;
@input
avatarPrefab!: ObjectPrefab;
onAwake() {
const spawn = this.instantiator.registerSpawn({
prefab: this.avatarPrefab,
scope: this,
ownership: Ownership.Owned,
});
spawn.onSpawned.add((root) => {
print(`Avatar spawned: ${root.instantiatedObject.name}`);
});
spawn.onDespawned.add(() => {
print('Avatar despawned');
});
}
}
A spawn declared Owned gives every client its own instance, owned by
whoever spawned it. A host-managed spawn gives one instance for the whole
session, created and deleted by the host, and it requires a customNetworkId
that is the same string on every client. Those two shapes are mutually
exclusive, which is why registerSpawn() rejects a host-managed spawn declared
as Owned.
Related
- Network Spawner: a simpler wrapper for the common case.
- Sync Entity
- Connected Framework overview