Skip to content

Component Reference

Every component type Awaken3D registers, with its fields, types, and defaults. Components are the data you attach to entities; systems and the renderer read them each frame. For the entity/component model see GameObjects & Components.

How components work

A component is plain data with no methods, described by a reflection spec. defineComponent(name, fields, create) returns a ComponentType whose fields are FieldSpecs - each a { name, type, default }. Because the spec is data:

  • Serialization is automatic. The scene serializer walks fields and reads/writes each one, so a new field ships with no serializer changes. See Data Formats.
  • The Inspector is automatic. Each FieldSpec.type picks an editor control - number → drag field, color → swatch, enum → dropdown, assetRef → asset picker, and so on. A showIf predicate can hide a field conditionally (e.g. a collider's radius when the shape is a mesh).

📸 Screenshot - save as img/api-inspector-reflection.png

The Inspector showing a selected object's components, with each FieldSpec.type rendered as its control (a color swatch, a vec3 triple, an enum dropdown) - the reflection-driven UI these field tables describe.

The enabled flag

Every component silently gains an enabled field (bool, default true), injected by defineComponent as ENABLED_FIELD. It mirrors Unity's Behaviour.enabled:

  • It is stored only when explicitly false - an enabled component writes nothing, keeping scenes lean.
  • Systems skip a disabled component (a disabled Light isn't gathered, a disabled Script slot tears down, a disabled Collider is excluded from collision tests).
  • It is hidden from the Inspector body (showIf returns false); the Inspector's per-component header checkbox drives it instead.

This lives on ComponentBase, which every component interface extends. It is separate from the entity-level active and Static flags, which live on the World (setActive/setStatic), not on any component.

The registered components

These seventeen types make up the editor's component registry (the add-menu, Inspector, and serializer all read from it). Field types come from FieldType.

Transform · @awaken/core

Local position/rotation/scale. Every visible or spatial object has one; it composes up the hierarchy into a world matrix.

FieldTypeDefault
positionvec3{0, 0, 0}
rotationquat{0, 0, 0, 1}
scalevec3{1, 1, 1}

See Transforms & Hierarchy.

MeshRenderer · @awaken/render

Makes an entity visible: which mesh to draw and its base PBR surface. opacity < 1 (or transparent) routes it to the alpha-blended pass.

FieldTypeDefault
meshassetRef"cube"
colorcolor[0.8, 0.8, 0.85]
metallicnumber0.0
roughnessnumber0.6
textureassetRef"" (none → white)
opacitynumber1.0
transparentboolfalse
castShadowbooltrue

See PBR & Lighting. Clear castShadow on a mesh that shouldn't drop a shadow (backdrops, ground fill). (The old per-renderer "static" flag is now the entity-level Static flag.)

The built-in mesh ids are cube, sphere, plane, quad, cylinder, and capsule. quad is a unit quad in the XY plane facing +Z (the plane builtin lies flat on XZ, so it is edge-on to a camera looking down -Z); the Add menu's 2D group ▸ Sprite builds a quad MeshRenderer with transparent: true and castShadow: false, to pair with an orthographic 2D camera.

MeshMaterial · @awaken/render

Attaches an authored Material (custom WGSL hooks) by id, overriding the default PBR shading.

FieldTypeDefault
materialassetRef"" (none)

The interface also carries a runtime overrides map (per-object parameter values), set through the Shader Editor rather than serialized as a reflected field.

Light · @awaken/render

A directional or point light. intensity scales the colour; range bounds a point light.

FieldTypeDefaultNotes
kindenum"directional"directional | point
colorcolor[1, 1, 1]
intensitynumber1
rangenumber10point-light falloff radius

See Shadows - the first directional light casts cascaded shadows.

Camera · @awaken/render

Defines the game camera's projection. The first active, enabled Camera is the render viewpoint in Game/Play; a second camera is ignored until the first is disabled or deleted.

FieldTypeDefaultNotes
projectionenum"perspective"perspective | orthographic
fovnumber60 (degrees)vertical FOV; perspective only
orthoSizenumber5half the view height in world units (Unity's orthographicSize); orthographic only
nearnumber0.1
farnumber1000

orthographic drops perspective foreshortening, so a sprite keeps the same on-screen size at any depth - the projection a 2D or isometric game uses. The Add menu's 2D group ▸ 2D Camera (Orthographic) spawns one preset to projection: "orthographic", orthoSize: 5. See Camera.

Animator · @awaken/runtime

Per-entity skeletal-animation playback state. References a clip + skeleton asset; the animation system samples the clip at time, builds bone matrices, and CPU-skins the mesh each frame. Only these are authored in the Inspector:

FieldTypeDefaultNotes
clipassetRef""hidden when an AnimStateMachine is present (the graph owns the clip)
skeletonassetRef""skeleton asset this entity is skinned to
speednumber1playback rate; negative reverses
loopbooltruehidden when an AnimStateMachine is present

The rest are runtime state - written by the animation system or scripts, hidden from the Inspector, but reflected fields so they persist:

  • Playback: playing (bool) and time (seconds into the clip).
  • Crossfade: fadeClip / fadeTime / fadeDuration / fadeElapsed. playClip(id, { fade, speed, loop }) starts a crossfade - while fadeClip is set the system samples both clips and blends the current pose toward the target over fade seconds (core blendPoses), then commits.
  • Play window: clipStart / clipEnd (plus fadeStart / fadeEnd), normalized [0,1] fractions of the clip's duration, so a state can play only a slice of a longer clip.
  • Root motion: rootDx / rootDz - the clip's character-local horizontal displacement this frame, read by a controller via api.rootMotion() to drive ground movement without foot-slide. flatRootY (bool) hands the animation's vertical to physics: while set, the system flattens the baked pelvis rise out of the pose and skips foot IK, so a physics jump doesn't double the clip's rise. A script flips it, e.g. api.setRootMotionVertical(!airborne).

A clip authored for one rig plays on a different character via humanoid cross-rig retargeting (per-slot bone mapping + auto-T-pose + geometric frame-map); auto-avatars are built at import, and a whole animation pack can import to rig-space clips before any character exists, then bind per character.

INFO

Skeletons, baked clips, and skins ride the exported .awaken.json / game.html container, and the animation system + foot IK run in the shipped player - animated characters animate in an export identically to editor Play.

Limitations

CPU skinning only (no GPU skinning path); up to 4 bone influences per vertex; glTF cubicspline tracks are sampled as linear. There are no blend-spaces / speed-matched locomotion yet.

See Animation.

AnimStateMachine · @awaken/runtime

Drives an Animator from an authored animation graph - states plus declarative-condition transitions - instead of hand-playing clips. Gameplay writes parameters (api.setAnimParam, api.setAnimTrigger); each frame the graph takes the first firing transition and crossfades the Animator to the target state's clip. The Animator may live on this entity or a child mesh, so a machine on a parent capsule drives the skinned child.

FieldTypeDefaultNotes
graphassetRef""the authored AnimGraph asset (or a built-in id)
clipsclipMap{}per-character binding: each state's logical clip name → this character's baked clip id
statestring""runtime-only active state (hidden; seeds to the graph's initial)

params (a live bag gameplay writes) is a plain object, not a reflected field - any param name works and it re-seeds from the graph's defaults, so it isn't serialized.

The graph is authored in the editor's Anim Graph tab. Transitions can fire from a specific state or from "*" (any state), gate on parameter conditions, and consume one-shot triggers. The clip binding (clips) is what makes one graph reusable across the hero and every NPC - each binds its own baked clips to the graph's logical names. A built-in LOCOMOTION_GRAPH (id builtin:locomotion) and a starter tps-locomotion graph ship ready to use.

See Animation and the ScriptApi Reference.

Ragdoll · @awaken/runtime

Hands a skinned character from animation to physics. When active flips true (via api.ragdoll(vx, vy, vz)), the current posed skeleton is handed to physics - a dynamic capsule per major humanoid bone, linked by spherical joints - and each frame the bodies are read back into the bone matrices so the mesh skins to the physics pose. The character crumples, collides with the world, and flops.

FieldTypeDefaultNotes
activeboolfalseset true to turn into a ragdoll; persists (a dead character stays a ragdoll)
seedVxnumber0world velocity every body inherits at activation (hidden runtime field)
seedVynumber0
seedVznumber0

Experimental

Joint limits are generous - the ragdoll flops loosely rather than posing realistically.

See Animation.

BoneAnchor · @awaken/runtime

Makes an entity a live mirror of one named skeleton bone: each frame the animation system writes that bone's animated local pose into the entity's Transform, so anything parented under the anchor - a sword under LeftHand, a hat under Head - rides the bone with the animation through the normal parent-transform composition (no special attach logic). The editor's "Expand skeleton" action spawns one anchor per bone, mirroring the bone hierarchy; a bone's owning character is the nearest ancestor carrying an Animator.

FieldTypeDefaultNotes
bonestring""skeleton bone name (stable across re-rigs, unlike an index)

See Animation.

RigidBody · @awaken/runtime

Marks an entity as physics-simulated. In Play it becomes a dynamic Rapier body.

FieldTypeDefault
velocityvec3{0, 0, 0}
useGravitybooltrue
restitutionnumber0.3 (bounciness)

See Rigidbody.

Collider · @awaken/runtime

A collision body made of one or more shapes (colliderShapes - a list rendered as Inspector blocks). A new Collider starts with a single box shape.

FieldTypeDefault
shapescolliderShapesone default box shape

Each ColliderShape has:

Shape fieldTypeDefaultNotes
kindenum"box"box | sphere | capsule | cylinder | mesh
centervec3{0, 0, 0}local offset
sizevec3{0.5, 0.5, 0.5}box half-extents
radiusnumber0.5sphere/capsule/cylinder
heightnumber2capsule/cylinder height
meshstring""kind:"mesh" asset id ("" = render mesh)
convexboolfalseconvex hull vs exact triangles
triggerboolfalsesensor: reports overlaps, doesn't block
enabledbooltrue
pinnedbool?(unset)keep the shape world-anchored, ignoring the object's own motion

See Colliders.

AudioSource · @awaken/runtime

Plays an audio clip, optionally on Play start.

FieldTypeDefault
clipassetRef"beep"
volumenumber1
loopboolfalse
playOnStartbooltrue

See Audio.

Script · @awaken/runtime

Attaches one or more script behaviours (scriptList - Inspector blocks). Each entry references a script by stable id and carries its per-instance parameter overrides + entity references.

FieldTypeDefault
scriptsscriptListone empty entry

Each ScriptEntry has name (script id), params (public-field overrides), refs (entity-reference fields), and enabled. See Script Parameters and the Code Panel.

Tag · @awaken/runtime

A string tag for lookup via api.findByTag, so a script finds an object by tag instead of by name (which changes when you rename it).

FieldTypeDefault
valuestring""

UINode · @awaken/runtime

A screen-space UI element (HUD text, a panel, a button, or an image), rendered as a DOM overlay in both the editor Game view and the shipped player. A UI element carries a Transform (so it is a first-class entity in the hierarchy/selection), but the overlay ignores it: position comes from anchor plus the pixel offsets, not the Transform.

FieldTypeDefaultNotes
kindenum"text"text | panel | button | image
anchorenum"top-left"9-point anchor (corners/edges/center)
xnumber20pixel offset from the anchor
ynumber20
wnumber00 = auto (fit content)
hnumber00 = auto
textstring"Text"
fontSizenumber24
colorcolor[1, 1, 1]text / foreground
bgcolor[0, 0, 0]panel / button background
opacitynumber0.5background alpha (and the image's alpha)
visiblebooltruescripts toggle via api.ui.show/hide
imagestring""kind:"image": imported texture/sprite id to draw (api.ui.setImage swaps it)
fitenum"contain"kind:"image": contain | cover | stretch - how the sprite fills w×h
rotationnumber0degrees clockwise about the centre (driven mostly by UI animation)
scaleXnumber1horizontal scale about the centre
scaleYnumber1vertical scale about the centre
fontstring""font-family: an imported .ttf/.otf name, or "" for the default system font

kind:"button" is the only clickable kind; text, panel, and image are click-through. See UI and Scripting UI.

UIAnimator · @awaken/runtime

Plays a UIClip on a UI widget - this entity plus its descendant UINodes, which the clip's tracks address by name. driveUIAnimators advances the playhead each frame and writes the sampled values (x/y/w/h/opacity/rotation/scale/colour) onto the nodes before the overlay syncs. UI clips are imported from Unity .anim files.

FieldTypeDefaultNotes
clipstring""UIClip id (from AssetStore.uiClips)
playingbooltruewhether the playhead advances; api.ui.play/stop toggle it
speednumber1playback rate (0 = frozen)
timenumber0runtime playhead in seconds (set to 0 to restart)

See UI and Scripting UI.

ParticleEmitter · @awaken/core

Plays a particle effect at this entity - fire, smoke, dust, a jet of sparks. The effect asset holds every tuning value; the component only says which effect and whether it is running.

FieldTypeDefaultNotes
effectassetRef""ParticleEffect asset id ("" = none). An unknown id is skipped silently - the emitter simply emits nothing.
playingbooltrueClear it to stop emitting; the emitter's particles and GPU buffers are released, and re-enabling starts a fresh pool.

Each frame the particle engine advances one live-particle pool per emitter and uploads the result to the renderer's billboard pass. An emitter is driven only when its whole subtree is active, the component is enabled, and playing is true.

The emitter's world transform is applied at spawn: it places the emission shape and aims the launch direction (the emitter's local +Y). Particles then live in world space, so a moving emitter trails its particles rather than carrying them.

INFO

Emitters simulate live while you edit, not only in Play - a frozen emitter would show nothing at all, so a placed campfire has to burn in the Viewport to be tunable. Scripted api.burst one-shots are the exception: scripts run in Play.

See Particles and the Particle Editor.

See also

Awaken — browser-native WebGPU game engine.