Physics
Physics manipulation on nodes via the Jolt backend. All methods are static on the Physics class. Methods operate on nodes that have physics bodies; they are no-ops if the node has no body.
Physics bodies are created automatically when a .blend is instantiated (if the Blender object has a Rigid Body) — see Resource.loadBlend. Bodies can also be created explicitly with addStaticBox and addDynamicBox. Configure collision layers and the collision matrix in game.toml.
Body creation
Section titled “Body creation”Physics.addStaticBox(scene, node, hx, hy, hz)
Section titled “Physics.addStaticBox(scene, node, hx, hy, hz)”Create a static box body (floor, wall, platform). The body position and rotation come from the node.
Parameters:
scene(Scene) — The scene whose physics world receives this body.node(Node) — The node to bind the body to.hx,hy,hz(Num) — Box half-extents on each axis.
Physics.addStaticBox(_scene, _floorNode, 10, 0.1, 10)Physics.addDynamicBox(scene, node, hx, hy, hz, mass)
Section titled “Physics.addDynamicBox(scene, node, hx, hy, hz, mass)”Create a dynamic box body (falling object, throwable prop).
Parameters:
scene(Scene) — The scene whose physics world receives this body.node(Node) — The node to bind the body to.hx,hy,hz(Num) — Box half-extents.mass(Num) — Mass in kg.
Physics.addDynamicBox(_scene, _cubeNode, 0.5, 0.5, 0.5, 1.0)Forces & impulses
Section titled “Forces & impulses”Forces are applied continuously (call each frame). Impulses are instantaneous.
Physics.addForce(node, fx, fy, fz)
Section titled “Physics.addForce(node, fx, fy, fz)”Apply a force at the center of mass. Call every frame for continuous acceleration.
Physics.addForceAtPoint(node, fx, fy, fz, px, py, pz)
Section titled “Physics.addForceAtPoint(node, fx, fy, fz, px, py, pz)”Apply a force at a world-space point. Off-center forces create torque.
Physics.addImpulse(node, ix, iy, iz)
Section titled “Physics.addImpulse(node, ix, iy, iz)”Apply an instantaneous impulse at the center of mass (single frame, no need to call each frame).
Physics.addImpulseAtPoint(node, ix, iy, iz, px, py, pz)
Section titled “Physics.addImpulseAtPoint(node, ix, iy, iz, px, py, pz)”Apply an instantaneous impulse at a world-space point.
Physics.addTorque(node, tx, ty, tz)
Section titled “Physics.addTorque(node, tx, ty, tz)”Apply angular force (torque) to the body.
// Kick a cube upward on Spaceif (Input.keyJustPressed("space")) { Physics.addImpulse(_cubeNode, 0, 10, 0)}// Continuous upward fan forcePhysics.addForce(_fanNode, 0, 50, 0)Position & rotation
Section titled “Position & rotation”Physics.setPosition(node, x, y, z) / Physics.setRotation(node, pitch, yaw, roll)
Section titled “Physics.setPosition(node, x, y, z) / Physics.setRotation(node, pitch, yaw, roll)”Teleport a body to a new position or rotation. Updates both the physics body and the node. Use for resets or warp-to-point.
// Reset cube on RPhysics.setPosition(_cubeNode, 0, 5, 0)Physics.setLinearVelocity(_cubeNode, 0, 0, 0)Physics.setAngularVelocity(_cubeNode, 0, 0, 0)Physics.activate(_cubeNode)Velocity
Section titled “Velocity”Physics.setLinearVelocity(node, vx, vy, vz) / Physics.getLinearVelocity(node)
Section titled “Physics.setLinearVelocity(node, vx, vy, vz) / Physics.getLinearVelocity(node)”Set or get the linear (translation) velocity. getLinearVelocity returns [vx, vy, vz].
Physics.setAngularVelocity(node, wx, wy, wz) / Physics.getAngularVelocity(node)
Section titled “Physics.setAngularVelocity(node, wx, wy, wz) / Physics.getAngularVelocity(node)”Set or get the angular (rotation) velocity. getAngularVelocity returns [wx, wy, wz].
Gravity
Section titled “Gravity”Physics.setGravity(scene, gx, gy, gz) / Physics.getGravity(scene)
Section titled “Physics.setGravity(scene, gx, gy, gz) / Physics.getGravity(scene)”Set or get the gravity vector for the scene’s physics world. Default is (0, -9.81, 0). getGravity returns [gx, gy, gz].
Physics.setGravity(_scene, 0, -20, 0) // Stronger gravityPhysics.setGravity(_scene, 0, 0, 0) // Zero-GSimulation control
Section titled “Simulation control”Physics.setSimulationPaused(scene, paused) / Physics.isSimulationPaused(scene)
Section titled “Physics.setSimulationPaused(scene, paused) / Physics.isSimulationPaused(scene)”Pause or resume the physics step for a scene. While paused, no bodies move but transforms still sync.
if (Input.keyJustPressed("p")) { var paused = Physics.isSimulationPaused(_scene) Physics.setSimulationPaused(_scene, !paused)}Physics.getBodyCount(scene)
Section titled “Physics.getBodyCount(scene)”Returns: Num — Number of active physics bodies in the scene’s world.
Physics.activate(node) / Physics.deactivate(node) / Physics.isActive(node)
Section titled “Physics.activate(node) / Physics.deactivate(node) / Physics.isActive(node)”Wake up or put to sleep a physics body. Dynamic bodies that come to rest are automatically deactivated by Jolt; use activate after a teleport or reset to ensure they simulate.
Physics raycasts
Section titled “Physics raycasts”These use the physics world (tests against Jolt broadphase, hits on physics-body nodes only). For raycasts against scene mesh geometry, see Raycast.
Physics.raycast(scene, ox, oy, oz, dx, dy, dz)
Section titled “Physics.raycast(scene, ox, oy, oz, dx, dy, dz)”Returns: RaycastHit or null — Closest physics body hit.
Parameters:
scene(Scene) — Scene whose physics world to test.ox,oy,oz(Num) — Ray origin.dx,dy,dz(Num) — Ray direction (does not need to be normalised; treated as direction vector).
Physics.raycastMaxDist(scene, ox, oy, oz, dx, dy, dz, maxDist)
Section titled “Physics.raycastMaxDist(scene, ox, oy, oz, dx, dy, dz, maxDist)”Same as raycast but limited to maxDist units.
var hit = Physics.raycast(_scene, 0, 10, 0, 0, -1, 0)if (hit != null) { Logger.info("Hit: %(hit.getNodeName()) at %(hit.getDistance())")}Contact events
Section titled “Contact events”Physics.onContactBegin(scene, callback) / Physics.onContactEnd(scene, callback)
Section titled “Physics.onContactBegin(scene, callback) / Physics.onContactEnd(scene, callback)”Register a callback fired when two physics bodies begin or end contact. Pass null to clear.
Callback signature: Fn.new { |nodeA, nodeB, pointX, pointY, pointZ, normalX, normalY, normalZ| ... }
nodeA,nodeB— The two Nodes involved.pointX/Y/Z— Contact point in world space.normalX/Y/Z— Contact normal.
Physics.onContactBegin(_scene, Fn.new { |nodeA, nodeB, px, py, pz, nx, ny, nz| if (nodeA.node_id == "player" || nodeB.node_id == "player") { Logger.info("Player touched %(nodeA.name)/%(nodeB.name)") }})See Scene for createCharacterController and createParticleEmitter. See Configuration for collision layer and collision matrix setup. See Raycast for mesh-level raycasts.