Skip to main content
Supported on
Snapchat

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

NameTypeDescription
Network IdHierarchy, Custom Id, or Object IdWhen 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 IdstringShown when Network Id is Custom Id. Must be the same string on every client. Defaults to enter_global_unique_id.
PrefabsObjectPrefab[]The prefabs this Instantiator may spawn. A prefab not in this list is rejected.
Spawner Owns ObjectbooleanIf enabled, the Instantiator owns what it spawns. Defaults to false.
Spawn As ChildrenbooleanIf enabled, instances are parented rather than created at the scene root. Defaults to false.
Spawn Under ParentSceneObjectShown when Spawn As Children is enabled. The parent for new instances.

Component API

Name (signature)Description
registerSpawn(declaration: SpawnDeclaration): SpawnDeclares 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(): booleanWhether the Instantiator is ready to spawn.
waitForReady(): Promise<void>Resolves once ready.
getSyncEntity(): SyncEntityThe Sync Entity backing this Instantiator.

SpawnDeclaration

FieldTypeDescription
prefabObjectPrefabRequired. Must be in the Prefabs list.
scopeBaseScriptComponent or SceneObjectRequired. The spawn lives as long as this scope does.
customNetworkIdstringRequired for a host-managed spawn, and must be globally unique.
ownershipOwnershipOwned, Unowned, or HostOwned.
persistencePersistenceEphemeral, Owner, Session, or Persist.
worldPosition / worldRotation / worldScalevec3 / quat / vec3Spawn transform in world space.
localPosition / localRotation / localScalevec3 / quat / vec3Spawn transform in local space.
localInstantiationContextunknownArbitrary 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().

NameDescription
instanceThe spawned NetworkRootInfo, or null before it exists.
isHostManagedWhether this is a single host-managed instance.
hasEndedWhether the spawn has ended.
customNetworkIdThe id passed at registration, or null.
onSpawnedEvent, called with the NetworkRootInfo.
onDespawnedEvent, 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.

Was this page helpful?
Yes
No