Skip to content

Prop Context Examples

TL;DR: A prop script runs on every client that sees the prop. Writes inside the prop’s own hierarchy are permitted; writes to world, avatars, or other props are not. Prop destruction comes for free via the CVR API, but only a world script may call it. State resets when the prop despawns unless you persist it yourself.

  • Read and write their own hierarchy.
  • Receive Unity lifecycle + physics events, OnPropSpawned, OnPropDespawned.
  • Respond to trigger/collision events on their own colliders.
  • Identify the spawner via Prop.GetCurrentProp().GetSpawner() and compare against LocalPlayer.PlayerObject (though LocalPlayer.* is world-only — so for avatar/prop, compare against the inbound Player arg in game events instead).
  • Send and receive network messages via WasmScripting.Networking.
  • Read CVR.CVRInput.* (for input-reactive widgets when the local player is the spawner).
  • Call LocalPlayer.* — world-only. Use game-event Player args to identify users.
  • Touch FileStorage / WorldPermissions / WorldSettings — world-only.
  • Call CVR_Prop_Destroy on themselves or any other prop — that binding is (World, Any, —). A prop wanting to self-destruct networks a “destroy me” signal to a world script that calls Destroy().
  • Mutate transforms outside the prop’s root.
  • Compare Player args, not LocalPlayer. Game events like OnPlayerTriggerEnter(Player) give you the interacting player directly; avatar/prop scripts should use that, since LocalPlayer.PlayerObject is world-only.
  • Use [WasmSerialized] for per-prop state you want to survive inspector → runtime serialization.
  • Cache hierarchy lookups — resolving prop.GetRootTransform() or prop.GetRootObject() each frame costs a host call. Cache in Start.
  • Networked state should flow through the spawner. The spawner is authoritative; other clients apply incoming messages.
  • Don’t assume prop state persists across despawns. When a prop despawns and respawns, you get a fresh VM. If the state has to survive, the spawner’s client must save it via a world-scoped escape hatch (another world script writing to FileStorage with the prop’s content ID as the filename).
  • Don’t expect LocalPlayer.* calls to work — they throw WasmAccessDeniedException.
  • Don’t call prop.Destroy() — needs a world script. Signal via network, have the world script actually destroy.
  • Don’t subscribe to OnPropSpawned thinking it’ll tell you “I just spawned” — it fires on all observers when any prop (yours or someone else’s) spawns. Use Start for “I just came alive”.
  • Don’t write [DefaultExecutionOrder] expecting it to order against Unity — it only orders among WasmBehaviours in the same VM.
  • Dice Roller — a 6-sided die you shake; owner rolls, everyone sees the same result; fully prop-scoped.