Skip to content


StaticMesh is a static CoreMesh. StaticMeshes can be placed in the scene and (if networked or client-only) moved at runtime, but the mesh itself cannot be animated.

See AnimatedMesh for meshes with animations.


Property Name Return Type Description Tags
isSimulatingDebrisPhysics boolean If true, physics will be enabled for the mesh. Read-Write, Client-Only


Function Name Return Type Description Tags
CanSimulateDebrisPhysics() boolean Returns whether or not the Static Mesh can simulate Debris Physics. None
SetMaterialForSlot(string assetId, string slotName) None Set the material in the given slot to the material specified by assetId. None
GetMaterialSlot(string slotName) MaterialSlot Get the MaterialSlot object for the given slot. If called on the client on a networked object, the resulting object cannot be modified. None
GetMaterialSlots() Array<MaterialSlot> Get an array of all MaterialSlots on this mesh. If called on the client on a networked object, the resulting object cannot be modified. None
ResetMaterialSlot(string slotName) None Resets a material slot to its original state. None
GetBoundingBox([table parameters]) Box Returns a Box describing the mesh bounds. The Box span may exceed the exact extrema of the object. Optional parameters can be provided to control the results:
inLocalSpace (boolean): If true, the box will describe the bounds in the mesh's local coordinate system. Defaults to false.
onlyCollidable (boolean): If true, the box will only describe the bounds of the mesh's collidable geometry. This can be affected by collision settings and network context. Defaults to false.


Example using:


In this example, the slotName property of all material slots belonging to the CUBE will be printed to the event log.

local CUBE = script.parent

-- Get an array of material slots
local MaterialSlots = CUBE:GetMaterialSlots()

-- Print the names of all material slots belonging to the "CUBE"
for index, materialSlot in ipairs(MaterialSlots) do

See also: MaterialSlot.slotName

Example using:



In this example a cube's material is changed at runtime. The script is placed as a child of the cube object and the desired material is assigned to the script as a custom property.

local CUBE = script.parent
local MATERIAL = script:GetCustomProperty("Material")

local matSlot = CUBE:GetMaterialSlots()[1]
CUBE:SetMaterialForSlot(MATERIAL, matSlot.slotName)

See also: MaterialSlot.slotName | CoreObject.parent

Example using:


The debris physics simulation is a client-only feature. The exact movement of simulated meshes is not expected to be the same across clients and should be used for visual effects, not for determining gameplay outcomes.

The following example takes several Static Meshes and explodes them randomly away from the epicenter. As written, it modifies only meshes that are children of the script object. When the player approaches the script at 3 meters or less then the function ExplodeChildren() is called, enabling the property isSimulatingDebrisPhysics for all the children, in addition to an impulse vector.

local hasExploded = false

function ExplodeChildren()
    local rng = RandomStream.New()

    local epicenter = script:GetWorldPosition()

    for _, child in ipairs(script:GetChildren()) do
        -- Enable client physics
        child.isSimulatingDebrisPhysics = true
        -- Impulse vector
        local direction = (child:GetWorldPosition() - epicenter):GetNormalized()
        child:SetVelocity((rng:GetVector3() + direction * 2) * EXPLOSION_FORCE)

function Tick()
    -- Call the explosion function only once
    if hasExploded then return end

    -- Detect if the local player has gotten close to the objects
    local player = Game.GetLocalPlayer()
    local distance = (player:GetWorldPosition() - script:GetWorldPosition()).size

    if distance < DISTANCE_TO_EXPLODE then
        hasExploded = true

See also: RandomStream.New | CoreObject.GetWorldPosition | Game.GetLocalPlayer | Player.GetWorldPosition | Vector3.GetNormalized | CoreLua.Tick

Last update: February 10, 2023