gameObject API reference
Signatures for transforms, physics, lookup, audio, GUI, hierarchy, vehicles, and constraints.
Identity, lookup, and variables
| Signature | Result |
|---|---|
gameObject.id | Current object UUID |
destroy() | Removes this object from the running simulation and returns true; false when the simulation is stopped or the object is already being removed (see Cross-object interactions) |
getVar(name) | number, string, boolean, object API, or nil |
setVar(name, value) | Sets a number, string, or boolean variable. It cannot set an object reference, and it does nothing on an object that has no variables at all, so define at least one on the object in the inspector first |
getObject(uuid) | Object API or nil |
getObjectByName(name) | Exact-name match or nil |
getObjectsByNamePrefix(prefix) | Array of object APIs |
getObjectsByType(type) | Array of object APIs |
Transforms and hierarchy
getPosition(), setPosition(x,y,z), getRotation(), setRotation(x,y,z,w), rotate(x,y,z), getParent(), getChildren(), setParent(parentIdOrNil), getWorldPosition(), getWorldRotation(), getWorldScale(), getLocalPosition(), getLocalRotation(), getLocalScale(), getForward(), getRight(), isRoot().
getForward() and getRight()
Both return world-space unit vectors. For an ordinary object they are derived from its world rotation, where local +Z is forward and local +X is right — the same convention characters and vehicles face along.
A camera is the exception. On a camera, getForward() returns the direction it is actually rendering and getRight() its screen-right. Three.js cameras look down their own local -Z while the rest of Airogel faces +Z, so deriving a camera's forward from its rotation the ordinary way would hand you the opposite of what the player sees; these two calls reconcile that for you.
That is what makes camera-relative movement work: read the active camera's forward and right, flatten them to the XZ plane if you do not want pitch, and use those as your movement axes instead of fixed world X/Z.
local camera = scene.getActiveCamera()
local forward = camera.getForward()
local right = camera.getRight()
getPosition() and getRotation() on a camera likewise return the pose it is rendering from, including a first_person or third_person camera that the engine is moving to follow its target, so a script reading the camera during update() sees what the player sees.
Physics and queries
addForce(x,y,z), addImpulse(x,y,z), addTorque(x,y,z), getLinearVelocity(), setLinearVelocity(x,y,z), getAngularVelocity(), setAngularVelocity(x,y,z), resetPhysicsState(x,y,z,qx?,qy?,qz?,qw?), registerForCollisions(), deregisterForCollisions(), raycast(direction,maxDistance,options?), sphereQuery(radius), boxQuery(halfExtents).
setPosition() deliberately preserves momentum. Use resetPhysicsState() for respawn or recovery: it teleports, applies the optional rotation, clears linear and angular velocity and vehicle driver input, then wakes the body.
On a soft body, push rather than assign. addForce, addImpulse and addTorque all work on one, but setLinearVelocity and setAngularVelocity do not: a soft body's velocity is recomputed from its vertices every step, so an assigned value is discarded by the next one and the object simply carries on as it was. The matching getters are fine — they read the body's real aggregate motion. Soft bodies also need far larger numbers than their size suggests, because their mass is their vertex count; see Physics, collisions, and triggers.
raycast(direction, maxDistance, options)
Returns an array of hits sorted nearest first. The ray stops at the nearest object in its way: the array can hold more than one hit, but never anything behind that object. On a miss it returns an empty array, never nil or false, so #hits == 0 is the miss check and if hits then is always true. A zero-length direction, a non-finite maxDistance, or a maxDistance of zero or less also return empty rather than raising.
Each hit is a table with exactly these four fields:
| Field | Value |
|---|---|
shape | UUID of the object that was hit. This is the id field — there is no id, objectId or bodyId on a hit. |
point | World-space contact point, as {x, y, z} |
distance | Metres from the ray origin |
fraction | Position along the ray, 0 to 1 of maxDistance |
There is no surface normal on a hit.
Behaviour worth knowing before you rely on it:
- The ray originates at the calling object's world position. To cast from a character's eye rather than its origin, resolve the camera and call
raycaston that handle instead. The camera sits inside the character's capsule, so pass the character inignore. directionis world-space and is not rotated by the calling object's transform. Passing{x=0, y=0, z=1}casts along world +Z, which is only "forward" for an unrotated object. For object-relative aiming, rotate the direction yourself, or passgetForward()— on a camera that is the direction the player is looking.directiondoes not need to be normalized; it is normalized for you.optionsis an optional table.ignorelists objects to pass through, as object handles or UUIDs, in a list or a single one.ignoreSensors = truepasses through trigger volumes, which are hit by default.ignoreSelf = falseincludes the calling object, which is ignored by default because a ray that starts inside it hits it at distance 0. These filter inside the query; skipping a hit in the script cannot reveal what is behind it, because nothing behind it was found. Example:gameObject.raycast(gameObject.getForward(), 100, { ignore = { player }, ignoreSensors = true }).- Before 9 October 2026 there were no options, and the results included the calling object.
sphereQuery(radius) and boxQuery(halfExtents) are centred on the calling object and return arrays of object UUIDs rather than hit tables. They also include the calling object when it has a collider.
Characters and animation
isOnGround(), getGroundInfo(), getCharacterVelocity(), setCharacterVelocity(x,y,z), jump(), setCrouched(crouched), isCrouched(), isInWater(), getWaterSubmersion(), getWalkSpeed(), getRunSpeed(), plus the animation API.
getGroundInfo() bundles the common ground-state fields into one call:
| Field | Value |
|---|---|
objectId | UUID of the object the character is standing on, or nil when it is not on ground it can stand on |
objectName | That object's name, or nil |
slopeAngle | Angle of the surface it is touching, in degrees |
isTooSteep | True when that surface is steeper than the character can stand on |
velocity | Velocity of the ground, as {x, y, z}, so a character can ride a moving platform |
normal | Surface normal as {x, y, z}, or nil when nothing is touched |
The same data is also available piecemeal via getGroundNormal(), getGroundVelocity(), getGroundObjectId(), getGroundObject(), getSlopeAngle(), and isSlopeTooSteep(). getUp() returns the character's current up vector (usually {x=0, y=1, z=0}).
getWaterSubmersion() returns how much of the character is under water, from 0 (dry) to 1 (fully submerged); isInWater() is true whenever it is above 0. setCrouched(crouched) returns false when the collider could not change — most often when standing up under something too low — and the character stays as it was, so call it again on a later frame.
getWalkSpeed() and getRunSpeed() return the character's Walk Speed and Run Speed inspector fields in metres per second, or nil on anything but a character. The engine never moves a character by them; they are there for a controller script to read, so speed can be tuned per character without editing the script. jump() does nothing unless the character is on ground it can stand on, except in water, where it swims upward at half the character's Jump Speed.
Rendering, GUI, and audio
getLightColor(), setLightColor(color), getLightIntensity(), setLightIntensity(value), getLightGroundColor(), setLightGroundColor(color), setText(text), setTextColor(r,g,b), setBackgroundColor(r,g,b,a), setFontSize(size), setVisible(visible), setImageAsset(assetId), setSize(width,height), setWidth(width), setHeight(height), setOpacity(opacity), setGuiPosition(x,y), setAnchor(anchor), setOrder(order), playSound(assetId, options), stopSound(soundId?, fadeOutSeconds?), isSoundPlaying(soundId).
GUI width and height are pixels. setGuiPosition is normalized 0–1 inside the container; it is deliberately separate from the 3D setPosition(x,y,z). setAnchor accepts topLeft, top, topRight, left, center, right, bottomLeft, bottom, or bottomRight. setOrder affects children of row/column panels. See Editor basics for the full authoring layout model.
Colour components run from 0 to 1, not 0 to 255. The light calls take a table — setLightColor({r=1, g=0.5, b=0}) — while the GUI calls take separate numbers — setTextColor(1, 0.5, 0). setText keeps the newlines and runs of spaces you write, so "Health: 3\nAmmo: 12" is two lines. setVisible works by setting opacity to 1 or 0, so setVisible(true) replaces a partial setOpacity; setOpacity clamps to 0–1.
playSound(assetId, options)
Plays a sound effect positioned at this object, which follows the object as it moves, and returns a sound id. Every call starts a new, independent instance, so calling it again while a looped sound is still playing layers a second copy rather than restarting the first. Keep the id if you will need to stop that instance. options is optional:
| Option | Meaning |
|---|---|
volume | 0–1, relative to the sound-effects volume. Default 1 |
loop | Repeat until stopped. Default false |
playbackRate | Speed multiplier; also shifts pitch. Default 1 |
fadeIn | Seconds to ramp up from silence |
refDistance, rolloffFactor, maxDistance | How the volume falls off with the listener's distance |
distanceModel | "linear", "inverse", or "exponential" |
stopSound(soundId, fadeOutSeconds?) stops one instance; stopSound() with no id stops every sound playing on this object. isSoundPlaying(soundId) reports whether an instance is still playing. For music and non-positional sound, see Scene scripts, variables, and storage.
Vehicles, constraints, navigation, and animation
These are also on every object API. Their behaviour and parameters are documented on the pages linked below.
| Area | Members |
|---|---|
| Wheeled vehicles (Vehicles and navigation) | setDriverInput(forward,right,brake,handBrake), setForwardInput(forward), setRightInput(right), setBrakeInput(brake), setHandBrakeInput(handBrake), getVehicleForwardSpeed(), getVehicleRPM(), getVehicleGear(), isWheelInContact(index), getWheelContactNormal(index) |
| Tracked vehicles | setTrackDriverInput(forward,leftRatio,rightRatio,brake), setLeftRatio(ratio), setRightRatio(ratio), plus the shared forward, brake, speed, RPM, gear and wheel-contact calls above |
| Hinge and slider motors | setConstraintMotorState("off"|"velocity"|"position"), setConstraintTargetVelocity(value), setConstraintTargetPosition(value), getConstraintCurrentValue() |
| Navigation agents | registerForPathfinding(speed?), moveTo(x,y,z), followPath(waypoints), stopMovement(), isMoving(), getPathToTarget(x,y,z), getRandomNavPoint(radius) |
| Generated tracks | getTrackPath() — the centreline of a generated track mesh, or nil |
| Animation (Animation playback API) | playAnimation(name,loop?,blendTime?), stopAnimation(name?,fadeOutTime?), setAnimationSpeed(speed,name?), getAnimationNames(), isAnimationPlaying(name?), enableAutoAnimation(config), disableAutoAnimation(), updateAutoAnimation(), getAnimationState(), preloadAnimations(names?), isAnimationReady(name), areAnimationsLoaded(), seekAnimation(name,time), getAnimationTime(name?), getAnimationDuration(name), getAnimationDiagnostics() |
| Bones and sockets (Animation playback API) | getBoneNames(), getBoneWorldPosition(name), getBoneWorldRotation(name), attachToBone(object,boneName,offset?), detachFromBone(object?), getBoneAttachments(). For characters and meshes with a skeleton; presentation-only in a multiplayer room |