World
world is a global singleton.
Objects
// Use these at runtime to add/remove objects
// Registers world-managed behavior on an object and its descendants.
// An unparented object is also attached to world.scene by default.
world.add(object: U.Object3D, addToScene: boolean = true)
// Remove an object and its descendants from runtime systems and the hierarchy
world.remove(object)
// list of objects that .update() each frame
world.objects -> Array of Objects
// list of objects which are raycasted each frame
world.raycastables -> Array of Objects
// make an object grabbable at runtime
world.addGrabbable(object)
// Register one mesh or text object for interaction raycasting
world.addRaycastable(mesh)
// Register a planar mesh for realtime planar reflections.
// Returns its stable reflection slot (0-7), or -1 if the geometry is not
// planar or all slots are occupied.
world.addPlanarReflection(mesh)
// Release a previously registered planar-reflection slot.
world.removePlanarReflection(mesh)
Up to eight planes may be registered. With one registered plane, its full-raster
cadence is controlled by SINGLE_REFLECTION_RASTER_INTERVAL in
Backend/PlanarReflection.js, and intervening eligible frames use reprojection.
With two or more registered planes, one eligible plane receives a full raster
capture per frame in round-robin order while the other eligible captures are
reprojected. Planes outside the camera frustum, hidden planes, and planes whose
front normal faces away from the camera are skipped. Both ordinary
BufferGeometry data and the packed geometry used by BatchedMesh are
supported. All vertex normals must point in roughly the same direction, and all
triangle faces must be roughly coplanar. The shared local normal is transformed
with the object, and the reflection plane passes through the transformed center
of the geometry bounding box. Removing a registered mesh with world.remove()
also releases its reflection slot.
Adding runtime objects
Use world.add(object) for a top-level runtime object. It discovers descendant
update/preUpdate callbacks and point/spot lights, then attaches an unparented
object to world.scene.
const model = await Model('prop.glb')
world.add(model)
For an ordinary visual child, parent.add(child) is enough: Unia synchronizes
the child and queues its descendants for rendering.
parent.add(model)
If a late-added subtree defines update/preUpdate callbacks or contains
point/spot lights, register that behavior after parenting it:
parent.add(child)
world.add(child)
Because child already has a parent, world.add() does not reparent it.
addToScene = false only suppresses automatic scene attachment for an
unparented object. Configure collider before adding a mesh. Raycasting is
separate and world.addRaycastable() accepts individual meshes or text, not a
Group.
Registered ordinary meshes and custom-shader meshes raycast their full CPU
triangle geometry by default. Set mesh.raycastBoundsOnly = true to use only
the mesh's world-space axis-aligned bounding box. The property is undefined by
default, and only strict true enables the bounds-only path. This can be useful
for vertex shaders that visually deform a mesh, provided the local
geometry.boundingBox contains the full deformation.
Avatars
world.avatars -> Map of avatar UUIDs to Objects
world.avatar -> Your avatar
// Distance in metres at which streamed avatar models become eligible to load.
// The default is 70. Avatar models unload 10 metres beyond this distance.
world.avatarLoadDistance -> number
Set world.avatarLoadDistance to suit the scale and sightlines of the project.
For example, a project that needs distant players to remain visible can set it
in index.js:
world.avatarLoadDistance = 120
An avatar inside this distance loads when it is in view. The unload distance is
always world.avatarLoadDistance + 10, which provides hysteresis near the load
boundary.
Other
// Exclude object from all raycasting
world.setRaycastable(Object3D, boolean)
// or use object.raycastable = false before adding to the scene
world.username -> 'yourUserName' | null
world.scene -> U.Scene
world.renderer -> WebGPU renderer interface
world.physics -> Physics global, see physics docs
world.nav -> JavaScript navigation heightfield service, see Navigation docs
world.storage -> Storage global, see storage docs
world.camera - > U.PerspectiveCamera, the player camera
world.animationMixer -> U.AnimationMixer, the main animation mixer
world.XR -> Boolean, whether we are in XR or not
world.startXR()
world.stats ->
{
triangles: number,
calls: number,
FPS: number,
}
Runtime mesh outlines
The renderer can outline one or more ordinary, non-skinned batched meshes. Pass all visible mesh children when highlighting a multipart model; groups and selection hitboxes are not expanded automatically.
world.renderer.setOutline(meshes, {
color: [1, 1, 1, 1],
width: 4, // screen pixels
xRay: false, // false keeps the outline behind scene depth
})
world.renderer.clearOutline()
The selection mask stores coverage and the nearest selected depth in two
channels. When xRay is
false, the outline is hidden by nearer scene geometry that writes depth,
including geometry in front of the selected object. xRay: true draws the
outline through that geometry. Translucent surfaces that do not write depth
cannot occlude it.
Only one runtime outline set is active at a time. Clear it when its owning gameplay system stops or removes the highlighted objects. Editor selection uses the same render pass but remains separate from the runtime target.
Scene triangle statistics
world.stats.triangles is the triangle count for the latest main scene frame,
including custom shaders, skinned meshes, text, UI, background, and impostors.
Each rendered instance contributes separately. Batched meshes use their selected
LOD and existing draw ranges after visibility and occlusion selection.
world.stats.customShaderTriangles is the custom shader portion of that total,
including indexed, non-indexed, and instanced geometry. Triangle lists use the
submitted index/vertex count divided by three, rounded down; triangle strips use
count minus two. Lines and points contribute zero triangles. Degenerate triangles
still count, as they do in conventional draw-count statistics.
Both XR eyes and repeated depth/color/UI passes share one frame count. Objects rendered in either eye count once. Shadow maps, reflection captures, outline postprocessing, and compute work do not add to this scene geometry count. Counts use existing draw metadata: no index scans, GPU readbacks, or GPU allocations. These values measure submitted scene triangles, not unique vertices, GPU memory, vertex shader invocations, or shader complexity.