Repository navigation
Rigidbody
Inspector name: Rigidbody · Lua: entity.rigidbody · Public field type: Rigidbody
A Rigidbody lets physics move an entity. It holds a velocity, and every frame the engine applies gravity to it and moves the entity by it. Pair it with a Collider so the entity lands on floors and stops at walls. The player needs one, and so does anything that should fall, be pushed or be launched.
Every frame, for every Rigidbody:
-
Gravity. If the entity is inside a sector and above the floor, its vertical velocity is
reduced by
level gravity × gravityScale × deltaTime. Standing on the floor, no gravity is added. -
Friction. The horizontal velocity (
xandz) is slowed toward zero byfrictionunits per second, every second. Vertical velocity isn't affected. -
Move. The entity's Transform moves by
velocity × deltaTime. -
Collide. If the entity has an active sphere Collider, physics pushes it out of
walls, other entities, the floor and the ceiling, removes the velocity going into them, and
updates
isGrounded.
An entity can have several Rigidbodies, but only the first one simulates. The others are kept with their settings and do nothing, and the inspector says so. To switch, drag another one to the top of the component list, or remove the first one from a script.
The level's Gravity (the Physics section of the level settings, default 9.8) is multiplied by the
Rigidbody's Gravity Scale (default 9.8). So a default body falls with an acceleration of about
96 units/s². To make one thing float or fall slowly, lower its Gravity Scale. 0 means no gravity.
Gravity only applies inside a sector and while the body is above the floor. Physics tracks the height above the floor for bodies with a sphere Collider, so give falling things a collider.
Is Static freezes the body: no gravity, and physics never moves it. Other bodies still collide with it. An entity with a Collider and no Rigidbody behaves the same way. Use static bodies for props that should block the player but never move.
isGrounded is true when physics found the body resting on a floor this frame (its feet within a
small distance of the floor and not moving away from it), or when it just climbed a step. The
Player Controller only jumps when it is true. It is recalculated every
frame, so writing it from a script has no lasting effect.
Mass is not used by the physics simulation yet. Collisions between two moving bodies always
push each one by half, whatever their masses. The only thing that reads it is AddImpulse, which
moves a heavy body less than a light one.
| Field | Lua | Default | Notes |
|---|---|---|---|
| Is Static | isStatic |
off | Frozen in place. |
| Mass | mass |
1 |
Only used by AddImpulse. |
| Gravity Scale | gravityScale |
9.8 |
Multiplies the level's gravity. |
| Friction | friction |
1 |
Horizontal slow-down, units/s per second. |
velocity isn't shown in the inspector. It starts at zero.
| Property | Type | Description | |
|---|---|---|---|
isValid |
boolean | read-only |
false if the entity or its Rigidbody is gone. |
velocity |
Vector3 | read/write | Units per second. |
isGrounded |
boolean | read/write | Resting on a floor this frame. Recalculated by physics every frame. |
isStatic |
boolean | read/write | |
mass |
number | read/write | Only used by AddImpulse. |
gravityScale |
number | read/write | |
friction |
number | read/write |
| Method | Description |
|---|---|
AddVelocity(v) |
Adds a Vector3 to the velocity. Every body gets the same change, whatever its mass. |
AddImpulse(impulse) |
Adds impulse / mass to the velocity, so heavier bodies move less. Good for explosions and knockback that should push a crate further than a boulder. A mass of 0 or less counts as 1. |
Stop() |
Sets the velocity to zero. |
rigidbody.velocity.y = 50 changes just the vertical speed. A velocity stored in a variable is a
copy, so assign it back after changing it.
On the player, the Player Controller pulls the horizontal velocity back toward what the movement keys ask for every frame, at its Acceleration / Deceleration rate, so horizontal pushes fade out. Vertical changes (jump pads, launches) work normally.
-- Scripts/JumpPad.lua (entity with a trigger Collider)
public number launchSpeed = 200
function OnTriggerEnter(other)
local body = other.rigidbody
if body == nil then return end
local v = body.velocity
body.velocity = Vector3(v.x, launchSpeed, v.z)
end-- Scripts/Barrel.lua (entity with a Collider)
-- Call barrel:GetScript("Barrel"):Explode() from another script.
public number radius = 96
public number force = 250
function Explode(self)
local center = entity.transform.position
for _, e in ipairs(Game.GetEntities()) do
local body = e.rigidbody
if e.id ~= entity.id and body ~= nil and not body.isStatic then
local offset = e.transform.position - center
local distance = offset.length
if distance < radius and distance > 0.001 then
local strength = force * (1 - distance / radius)
body:AddImpulse(offset.normalized * strength + Vector3(0, strength * 0.5, 0))
end
end
end
entity:Destroy()
end(Against the player only the upward part has an effect, as explained above.)
-- Scripts/LowGravity.lua (on anything with a Rigidbody)
-- Floaty physics in sectors tagged "lowgravity".
public number lowScale = 2
local normalScale
function Start()
normalScale = entity.rigidbody.gravityScale
end
function OnSectorChange(sector)
local low = sector ~= nil and sector:HasTag("lowgravity")
entity.rigidbody.gravityScale = low and lowScale or normalScale
end-- Scripts/HangingCrate.lua (entity with a Collider and a static Rigidbody, placed in the air)
-- Another script calls crate:GetScript("HangingCrate"):Drop()
function Drop(self)
entity.rigidbody.isStatic = false
endA static body floating in the air starts falling as soon as it's made non-static. It lands on the floor below, because its sphere Collider keeps track of the floor under it.