BasePart

Show Deprecated
Not Creatable
Not Browsable

BasePart is an abstract base class for in-world objects that render and are physically simulated while in the Workspace. There are several implementations of BasePart, the most common being Part and MeshPart. Others include WedgePart, SpawnLocation, and the singleton Terrain object. Generally, when documentation refers to a "part," most BasePart implementations will work and not just Part.

For information on how BaseParts are grouped into simulated rigid bodies, see Assemblies.

There are many different objects that interact with BasePart (other than Terrain), including:

Summary

Properties

  • Read Parallel

    Determines whether a part is immovable by physics.

  • Not Replicated
    Read Parallel

    The angular velocity of the part's assembly.

  • Read Only
    Not Replicated
    Read Parallel

    The center of mass of the part's assembly in world space.

  • Not Replicated
    Read Parallel

    The linear velocity of the part's assembly.

  • Read Only
    Not Replicated
    Read Parallel

    The total mass of the part's assembly.

  • Read Only
    Not Replicated
    Read Parallel

    A reference to the root part of the assembly.

  • Read Parallel
  • Hidden
    Deprecated
    Read Parallel

    Determines the first parameter for the SurfaceType on the Back face of a part (+Z direction).

  • Hidden
    Deprecated
    Read Parallel

    Determines the second parameter for the SurfaceType on the Back face of a part (+Z direction).

  • Determines the type of surface for the Back face of a part (+Z direction).

  • Hidden
    Deprecated
    Read Parallel

    Determines the kind of input for the Back face of a part (+Z direction).

  • Hidden
    Deprecated
    Read Parallel

    Determines the first parameter for the SurfaceType on the Bottom face of a part (-Y direction).

  • Hidden
    Deprecated
    Read Parallel

    Determines the second parameter for the SurfaceType on the Bottom face of a part (-Y direction).

  • Determines the type of surface for the Bottom face of a part (-Y direction).

  • Hidden
    Deprecated
    Read Parallel

    Determines the kind of input for the Bottom face of a part (-Y direction).

  • Not Replicated
    Read Parallel

    Determines the color of a part.

  • Read Parallel

    Determines the position and orientation of the BasePart in the world.

  • Read Parallel

    Determines whether a part may collide with other parts.

  • Read Parallel

    Determines whether the part is considered during spatial query operations.

  • Read Parallel

    Determines if Touched and TouchEnded events fire on the part.

  • Read Parallel

    Determines whether or not a part casts a shadow.

  • Read Only
    Not Replicated
    Read Parallel

    Describes the world position in which a part's center of mass is located.

  • Not Replicated
    Read Parallel

    Describes the name of a part's collision group.

  • Not Replicated
    Deprecated
    Read Parallel

    Describes the automatically set ID number of a part's collision group.

  • Not Replicated
    Read Parallel

    Determines the color of a part.

  • Read Only
    Not Replicated
    Read Parallel

    Indicates the current physical properties of the part.

  • Determines several physical properties of a part.

  • Hidden
    Not Replicated
    Deprecated
    Read Parallel

    Used to control the Elasticity of the part, but it no longer does anything.

  • Read Parallel

    Used to enable or disable aerodynamic forces on parts and assemblies.

  • Read Only
    Not Replicated
    Read Parallel

    The CFrame of the physical extents of the BasePart.

  • Read Only
    Not Replicated
    Read Parallel

    The actual physical size of the BasePart as regarded by the physics engine.

  • Hidden
    Not Replicated
    Deprecated
    Read Parallel

    Used to control the Friction of the part, but now it no longer does anything.

  • Hidden
    Deprecated
    Read Parallel

    Determines the first parameter for the SurfaceType on the Front face of a part (-Z direction).

  • Hidden
    Deprecated
    Read Parallel

    Determines the second parameter for the SurfaceType on the Front face of a part (-Z direction).

  • Determines the type of surface for the Front face of a part (-Z direction).

  • Hidden
    Deprecated
    Read Parallel

    Determines the kind of input for the Front face of a part (-Z direction).

  • Hidden
    Deprecated
    Read Parallel

    Determines the first parameter for the SurfaceType on the Left face of a part (-Z direction).

  • Hidden
    Deprecated
    Read Parallel

    Determines the second parameter for the SurfaceType on the Left face of a part (-Z direction).

  • Determines the type of surface for the Left face of a part (-X direction).

  • Hidden
    Deprecated
    Read Parallel

    Determines the kind of input for the Left face of a part (+X direction).

  • Hidden
    Not Replicated
    Read Parallel

    Determines a multiplier for BasePart.Transparency that is only visible to the local client.

  • Read Parallel

    Determines whether a part is selectable in Studio.

  • Read Only
    Not Replicated
    Read Parallel

    Describes the mass of the part, the product of its density and volume.

  • Read Parallel

    Determines whether the part contributes to the total mass or inertia of its rigid body.

  • Read Parallel

    Determines the texture and default physical properties of a part.

  • Not Replicated
    Read Parallel

    The name of MaterialVariant.

  • Hidden
    Not Replicated
    Read Parallel

    Describes the rotation of the part in the world.

  • Read Parallel

    Specifies the offset of the part's pivot from its CFrame.

  • Hidden
    Not Replicated
    Read Parallel

    Describes the position of the part in the world.

  • Hidden
    Read Only
    Not Replicated
    Read Parallel

    Time since last recorded physics update.

  • Read Parallel

    Determines how much a part reflects the skybox.

  • Read Only
    Not Replicated
    Read Parallel

    Describes the smallest change in size allowable by the Resize method.

  • Read Only
    Not Replicated
    Read Parallel

    Describes the faces on which a part may be resized.

  • Hidden
    Deprecated
    Read Parallel

    Determines the first parameter for the SurfaceType on the Right face of a part (-X direction).

  • Hidden
    Deprecated
    Read Parallel

    Determines the second parameter for the SurfaceType on the Right face of a part (-X direction).

  • Determines the type of surface for the Right face of a part (+X direction).

  • Hidden
    Deprecated
    Read Parallel

    Determines the kind of input for the Right face of a part (-X direction).

  • Read Parallel

    The main rule in determining the root part of an assembly.

  • Hidden
    Deprecated
    Read Parallel

    Determines a part's change in orientation over time.

  • Not Replicated
    Read Parallel

    The rotation of the part in degrees for the three axes.

  • Not Replicated
    Read Parallel

    Determines the dimensions of a part (length, width, height).

  • Read Only
    Not Replicated
    Deprecated
    Read Parallel

    The ratio of the part's density to the density of water determined by the BasePart.Material.

  • Hidden
    Deprecated
    Read Parallel

    Determines the first parameter for the SurfaceType on the Top face of a part (+Y direction).

  • Hidden
    Deprecated
    Read Parallel

    Determines the second parameter for the SurfaceType on the Top face of a part (+Y direction).

  • Determines the type of surface for the Top face of a part (+Y direction).

  • Hidden
    Deprecated
    Read Parallel

    Determines the kind of input for the Top face of a part (+Y direction).

  • Read Parallel

    Determines how much a part can be seen through (the inverse of part opacity).

  • Hidden
    Deprecated
    Read Parallel

    Determines a part's change in position over time.

  • Not Replicated
    Deprecated
    Read Parallel
Properties inherited from PVInstance

Methods

Methods inherited from PVInstance

Events

Properties

Anchored

Read Parallel

The Anchored property determines whether the part will be immovable by physics. When enabled, a part will never change position due to gravity, other part collisions, overlapping other parts, or any other physics-related causes. As a result, two anchored parts will never fire the BasePart.Touched event on each other.

An anchored part may still be moved by changing its CFrame or Position, and it still may have a nonzero AssemblyLinearVelocity and AssemblyAngularVelocity.

Finally, if an unanchored part is joined with an anchored part through an object like a Weld, it too will act anchored. If such a joint breaks, the part may be affected by physics again. See Assemblies for more details.

Network ownership cannot be set on anchored parts. If a part's anchored status changes on the server, the network ownership of that part will be affected.

Code Samples

This code sample will allow a part to be clicked to toggle its anchored property. When toggled, the visual appearance of the part is updated (red means anchored, yellow means free).

Part Anchored Toggle

local part = script.Parent
-- Create a ClickDetector so we can tell when the part is clicked
local cd = Instance.new("ClickDetector", part)
-- This function updates how the part looks based on its Anchored state
local function updateVisuals()
if part.Anchored then
-- When the part is anchored...
part.BrickColor = BrickColor.new("Bright red")
part.Material = Enum.Material.DiamondPlate
else
-- When the part is unanchored...
part.BrickColor = BrickColor.new("Bright yellow")
part.Material = Enum.Material.Wood
end
end
local function onToggle()
-- Toggle the anchored property
part.Anchored = not part.Anchored
-- Update visual state of the brick
updateVisuals()
end
-- Update, then start listening for clicks
updateVisuals()
cd.MouseClick:Connect(onToggle)

AssemblyAngularVelocity

Not Replicated
Read Parallel

The angular velocity vector of this part's assembly. It's the rate of change of orientation in radians per second.

Angular velocity is the same at every point of the assembly.

Setting the velocity directly may lead to unrealistic motion. Using Torque or AngularVelocity constraint is preferred, or use BasePart:ApplyAngularImpulse() if you want instantaneous change in velocity.

If the part is owned by the server, this property must be changed from a server Script (not from a LocalScript or a Script with RunContext set to Enum.RunContext.Client). If the part is owned by a client through automatic ownership, this property can be changed from either a client script or a server script; changing it from a client script for a server-owned part will have no effect.

AssemblyCenterOfMass

Read Only
Not Replicated
Read Parallel

A position calculated via the mass and position of all the parts in the assembly.

If the assembly has an anchored part, that part's center of mass will be the assembly's center of mass, and the assembly will have infinite mass.

Knowing the center of mass can help the assembly maintain stability. A force applied to the center of mass will not cause angular acceleration, only linear. An assembly with a low center of mass will have a better time staying upright under the effect of gravity.

AssemblyLinearVelocity

Not Replicated
Read Parallel

The linear velocity vector of this part's assembly. It's the rate of change in position of the assembly's center of mass in studs per second.

If you want to know the velocity at a point other than the assembly's center of mass, use BasePart:GetVelocityAtPosition().

Setting the velocity directly may lead to unrealistic motion. Using a VectorForce constraint is preferred, or use BasePart:ApplyImpulse() if you want instantaneous change in velocity.

If the part is owned by the server, this property must be changed from a server Script (not from a LocalScript or a Script with RunContext set to Enum.RunContext.Client). If the part is owned by a client through automatic ownership, this property can be changed from either a client script or a server script; changing it from a client script for a server-owned part will have no effect.

AssemblyMass

Read Only
Not Replicated
Read Parallel

The sum of the mass of all the parts in this part's assembly. Parts that are Massless and are not the assembly's root part will not contribute to the AssemblyMass.

If the assembly has an anchored part, the assembly's mass is considered infinite. Constraints and other physical interactions between unanchored assemblies with a large difference in mass may cause instabilities.

AssemblyRootPart

Read Only
Not Replicated
Read Parallel

This property indicates the BasePart automatically chosen to represent the assembly's root part. It is the same part that's returned when developers call GetRootPart().

The root part can be changed by changing the RootPriority of the parts in the assembly.

Parts that all share the same AssemblyRootPart are in the same assembly.

For more information on root parts, see Assemblies.

AudioCanCollide

Read Parallel

BackParamA

Hidden
Deprecated
Read Parallel

The BackParamA property is relevant when a part's BasePart.BackSurface is set to Motor or SteppingMotor and BasePart.BackSurfaceInput is set to Sin. It determines the amplitude of the motor's rotational velocity, using the following formula:

MotorVelocity = ParamA * math.sin(workspace.DistributedGameTime * ParamB)

There are no other usages for this property.

Code Samples

Motor Control

-- Paste this into a Script inside a part with a Motor SurfaceType
local partMotor = script.Parent
-- Place a brick called "MovingPart" so it is touching the Motor surface
-- For this example, we use TopSurface, TopSurfaceInput, TopParamA and TopParamB
-- However, this will work for all faces (NormalId): Top, Bottom, Left, Right, Front and Back
-- A function to quickly set all surface properties at once
local function setFaceSurfaceInputParams(normalId, surfaceType, inputType, paramA, paramB)
local surfaceName = normalId.Name -- e.g. "Top", "Bottom", etc
-- Syntax Note: in Lua, part.Something is the same as part["Something"]
-- The difference is that the latter allows us to use a string ("Something"), while
-- the former requires use of an identifier (.Something). Below, we build of each the surface
-- properties below by concatenating the surface name with the property postfix.
-- Set "___Surface", eg "TopSurface"
partMotor[surfaceName .. "Surface"] = surfaceType
-- Set "___SurfaceInput", eg "TopSurfaceInput"
partMotor[surfaceName .. "SurfaceInput"] = inputType
-- Set "___ParamA", eg "TopParamA"
partMotor[surfaceName .. "ParamA"] = paramA
-- Set "___ParamB", eg "TopParamB"
partMotor[surfaceName .. "ParamB"] = paramB
end
local normalId = Enum.NormalId.Top
while true do
-- Set to NoInput, where the motor will not operate at all
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.NoInput, 0, 0)
task.wait(1)
-- Set to Constant, where motor rotational velocity = paramB
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Constant, 0, 0.25)
task.wait(2)
-- Set to Sin, where motor rotational velocity = paramA * math.sin(time * paramB)
-- Since we're using pi (~3.14), the frequency of rotation is 1 second (per definition of sine function)
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Sin, 0.25, math.pi)
task.wait(3)
end

BackParamB

Hidden
Deprecated
Read Parallel

The BackParamB property is relevant when a part's BasePart.BackSurface is set to Motor or SteppingMotor and BasePart.BackSurfaceInput is set to Constant or Sin. For Constant, it determines the constant rotational velocity of the motor. For Sin, it determines the frequency of the motor's rotational velocity, using the following formula:

MotorVelocity = ParamB * math.sin(workspace.DistributedGameTime * ParamB)

In no other cases is this property used.

Code Samples

Motor Control

-- Paste this into a Script inside a part with a Motor SurfaceType
local partMotor = script.Parent
-- Place a brick called "MovingPart" so it is touching the Motor surface
-- For this example, we use TopSurface, TopSurfaceInput, TopParamA and TopParamB
-- However, this will work for all faces (NormalId): Top, Bottom, Left, Right, Front and Back
-- A function to quickly set all surface properties at once
local function setFaceSurfaceInputParams(normalId, surfaceType, inputType, paramA, paramB)
local surfaceName = normalId.Name -- e.g. "Top", "Bottom", etc
-- Syntax Note: in Lua, part.Something is the same as part["Something"]
-- The difference is that the latter allows us to use a string ("Something"), while
-- the former requires use of an identifier (.Something). Below, we build of each the surface
-- properties below by concatenating the surface name with the property postfix.
-- Set "___Surface", eg "TopSurface"
partMotor[surfaceName .. "Surface"] = surfaceType
-- Set "___SurfaceInput", eg "TopSurfaceInput"
partMotor[surfaceName .. "SurfaceInput"] = inputType
-- Set "___ParamA", eg "TopParamA"
partMotor[surfaceName .. "ParamA"] = paramA
-- Set "___ParamB", eg "TopParamB"
partMotor[surfaceName .. "ParamB"] = paramB
end
local normalId = Enum.NormalId.Top
while true do
-- Set to NoInput, where the motor will not operate at all
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.NoInput, 0, 0)
task.wait(1)
-- Set to Constant, where motor rotational velocity = paramB
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Constant, 0, 0.25)
task.wait(2)
-- Set to Sin, where motor rotational velocity = paramA * math.sin(time * paramB)
-- Since we're using pi (~3.14), the frequency of rotation is 1 second (per definition of sine function)
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Sin, 0.25, math.pi)
task.wait(3)
end

BackSurface

Read Parallel

The BackSurface property determines the type of surface used for the +Z direction of a part. When two parts' faces are placed next to each other, they may create a joint between them. If set to Motor, the BasePart.BackSurfaceInput determines how a motor joint should behave.

Most SurfaceTypes render a texture on the part face if the BasePart.Material is set to Plastic. Some SurfaceTypes - Hinge, Motor and SteppingMotor - will render a 3D adornment instead. If this property is selected in the Properties window, it will be highlighted in the game world similar to that of a SurfaceSelection.

Code Samples

This code sample shows what each SurfaceType looks like on a part. In addition, it creates a BillboardGui label on the part with a TextLabel that reflects the name of the current SurfaceType.

Show All SurfaceTypes

local demoPart = script.Parent
-- Create a billboard gui to display what the current surface type is
local billboard = Instance.new("BillboardGui")
billboard.AlwaysOnTop = true
billboard.Size = UDim2.new(0, 200, 0, 50)
billboard.Adornee = demoPart
local textLabel = Instance.new("TextLabel")
textLabel.Size = UDim2.new(0, 200, 0, 50)
textLabel.BackgroundTransparency = 1
textLabel.TextStrokeTransparency = 0
textLabel.TextColor3 = Color3.new(1, 1, 1) -- White
textLabel.Parent = billboard
billboard.Parent = demoPart
local function setAllSurfaces(part, surfaceType)
part.TopSurface = surfaceType
part.BottomSurface = surfaceType
part.LeftSurface = surfaceType
part.RightSurface = surfaceType
part.FrontSurface = surfaceType
part.BackSurface = surfaceType
end
while true do
-- Iterate through the different SurfaceTypes
for _, enum in pairs(Enum.SurfaceType:GetEnumItems()) do
textLabel.Text = enum.Name
setAllSurfaces(demoPart, enum)
task.wait(1)
end
end

BackSurfaceInput

Hidden
Deprecated
Read Parallel

The BackSurfaceInput property determines the kind of input provided to a part's BasePart.BackSurface. This is only relevant for Motor or SteppingMotor SurfaceTypes. This property determines how BasePart.BackParamA and BasePart.BackParamB are used. For brevity, these properties will be referred to as ParamA and ParamB, respectively.

  • By default, this is set to NoInput. This stops the motor altogether.
  • For Constant, the motor rotates at a constant velocity equal to ParamB.
  • For Sin, the motor rotates at a velocity equal to ParamA * math.sin(workspace.DistributedGameTime * ParamB). See Workspace.DistributedGameTime.

Code Samples

Motor Control

-- Paste this into a Script inside a part with a Motor SurfaceType
local partMotor = script.Parent
-- Place a brick called "MovingPart" so it is touching the Motor surface
-- For this example, we use TopSurface, TopSurfaceInput, TopParamA and TopParamB
-- However, this will work for all faces (NormalId): Top, Bottom, Left, Right, Front and Back
-- A function to quickly set all surface properties at once
local function setFaceSurfaceInputParams(normalId, surfaceType, inputType, paramA, paramB)
local surfaceName = normalId.Name -- e.g. "Top", "Bottom", etc
-- Syntax Note: in Lua, part.Something is the same as part["Something"]
-- The difference is that the latter allows us to use a string ("Something"), while
-- the former requires use of an identifier (.Something). Below, we build of each the surface
-- properties below by concatenating the surface name with the property postfix.
-- Set "___Surface", eg "TopSurface"
partMotor[surfaceName .. "Surface"] = surfaceType
-- Set "___SurfaceInput", eg "TopSurfaceInput"
partMotor[surfaceName .. "SurfaceInput"] = inputType
-- Set "___ParamA", eg "TopParamA"
partMotor[surfaceName .. "ParamA"] = paramA
-- Set "___ParamB", eg "TopParamB"
partMotor[surfaceName .. "ParamB"] = paramB
end
local normalId = Enum.NormalId.Top
while true do
-- Set to NoInput, where the motor will not operate at all
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.NoInput, 0, 0)
task.wait(1)
-- Set to Constant, where motor rotational velocity = paramB
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Constant, 0, 0.25)
task.wait(2)
-- Set to Sin, where motor rotational velocity = paramA * math.sin(time * paramB)
-- Since we're using pi (~3.14), the frequency of rotation is 1 second (per definition of sine function)
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Sin, 0.25, math.pi)
task.wait(3)
end

BottomParamA

Hidden
Deprecated
Read Parallel

The BottomParamA property is relevant when a part's BasePart.BottomSurface is set to Motor or SteppingMotor and BasePart.BottomSurfaceInput is set to Sin. It determines the amplitude of the motor's rotational velocity, using the following formula:

MotorVelocity = ParamA * math.sin(workspace.DistributedGameTime * ParamB)

There are no other usages for this property.

Code Samples

Motor Control

-- Paste this into a Script inside a part with a Motor SurfaceType
local partMotor = script.Parent
-- Place a brick called "MovingPart" so it is touching the Motor surface
-- For this example, we use TopSurface, TopSurfaceInput, TopParamA and TopParamB
-- However, this will work for all faces (NormalId): Top, Bottom, Left, Right, Front and Back
-- A function to quickly set all surface properties at once
local function setFaceSurfaceInputParams(normalId, surfaceType, inputType, paramA, paramB)
local surfaceName = normalId.Name -- e.g. "Top", "Bottom", etc
-- Syntax Note: in Lua, part.Something is the same as part["Something"]
-- The difference is that the latter allows us to use a string ("Something"), while
-- the former requires use of an identifier (.Something). Below, we build of each the surface
-- properties below by concatenating the surface name with the property postfix.
-- Set "___Surface", eg "TopSurface"
partMotor[surfaceName .. "Surface"] = surfaceType
-- Set "___SurfaceInput", eg "TopSurfaceInput"
partMotor[surfaceName .. "SurfaceInput"] = inputType
-- Set "___ParamA", eg "TopParamA"
partMotor[surfaceName .. "ParamA"] = paramA
-- Set "___ParamB", eg "TopParamB"
partMotor[surfaceName .. "ParamB"] = paramB
end
local normalId = Enum.NormalId.Top
while true do
-- Set to NoInput, where the motor will not operate at all
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.NoInput, 0, 0)
task.wait(1)
-- Set to Constant, where motor rotational velocity = paramB
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Constant, 0, 0.25)
task.wait(2)
-- Set to Sin, where motor rotational velocity = paramA * math.sin(time * paramB)
-- Since we're using pi (~3.14), the frequency of rotation is 1 second (per definition of sine function)
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Sin, 0.25, math.pi)
task.wait(3)
end

BottomParamB

Hidden
Deprecated
Read Parallel

The BottomParamB property is relevant when a part's BasePart.BottomSurface is set to Motor or SteppingMotor and BasePart.BottomSurfaceInput is set to Constant or Sin. For Constant, it determines the constant rotational velocity of the motor. For Sin, it determines the frequency of the motor's rotational velocity, using the following formula:

MotorVelocity = ParamB * math.sin(workspace.DistributedGameTime * ParamB)

In no other cases is this property used.

Code Samples

Motor Control

-- Paste this into a Script inside a part with a Motor SurfaceType
local partMotor = script.Parent
-- Place a brick called "MovingPart" so it is touching the Motor surface
-- For this example, we use TopSurface, TopSurfaceInput, TopParamA and TopParamB
-- However, this will work for all faces (NormalId): Top, Bottom, Left, Right, Front and Back
-- A function to quickly set all surface properties at once
local function setFaceSurfaceInputParams(normalId, surfaceType, inputType, paramA, paramB)
local surfaceName = normalId.Name -- e.g. "Top", "Bottom", etc
-- Syntax Note: in Lua, part.Something is the same as part["Something"]
-- The difference is that the latter allows us to use a string ("Something"), while
-- the former requires use of an identifier (.Something). Below, we build of each the surface
-- properties below by concatenating the surface name with the property postfix.
-- Set "___Surface", eg "TopSurface"
partMotor[surfaceName .. "Surface"] = surfaceType
-- Set "___SurfaceInput", eg "TopSurfaceInput"
partMotor[surfaceName .. "SurfaceInput"] = inputType
-- Set "___ParamA", eg "TopParamA"
partMotor[surfaceName .. "ParamA"] = paramA
-- Set "___ParamB", eg "TopParamB"
partMotor[surfaceName .. "ParamB"] = paramB
end
local normalId = Enum.NormalId.Top
while true do
-- Set to NoInput, where the motor will not operate at all
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.NoInput, 0, 0)
task.wait(1)
-- Set to Constant, where motor rotational velocity = paramB
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Constant, 0, 0.25)
task.wait(2)
-- Set to Sin, where motor rotational velocity = paramA * math.sin(time * paramB)
-- Since we're using pi (~3.14), the frequency of rotation is 1 second (per definition of sine function)
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Sin, 0.25, math.pi)
task.wait(3)
end

BottomSurface

Read Parallel

The BottomSurface property determines the type of surface used for the -Y direction of a part. When two parts' faces are placed next to each other, they may create a joint between them. If set to Motor, the BasePart.BottomSurfaceInput determines how a motor joint should behave.

Most SurfaceTypes render a texture on the part face if the BasePart.Material is set to Plastic. Some SurfaceTypes - Hinge, Motor and SteppingMotor - will render a 3D adornment instead. If this property is selected in the Properties window, it will be highlighted in the game world similar to that of a SurfaceSelection.

Code Samples

This code sample shows what each SurfaceType looks like on a part. In addition, it creates a BillboardGui label on the part with a TextLabel that reflects the name of the current SurfaceType.

Show All SurfaceTypes

local demoPart = script.Parent
-- Create a billboard gui to display what the current surface type is
local billboard = Instance.new("BillboardGui")
billboard.AlwaysOnTop = true
billboard.Size = UDim2.new(0, 200, 0, 50)
billboard.Adornee = demoPart
local textLabel = Instance.new("TextLabel")
textLabel.Size = UDim2.new(0, 200, 0, 50)
textLabel.BackgroundTransparency = 1
textLabel.TextStrokeTransparency = 0
textLabel.TextColor3 = Color3.new(1, 1, 1) -- White
textLabel.Parent = billboard
billboard.Parent = demoPart
local function setAllSurfaces(part, surfaceType)
part.TopSurface = surfaceType
part.BottomSurface = surfaceType
part.LeftSurface = surfaceType
part.RightSurface = surfaceType
part.FrontSurface = surfaceType
part.BackSurface = surfaceType
end
while true do
-- Iterate through the different SurfaceTypes
for _, enum in pairs(Enum.SurfaceType:GetEnumItems()) do
textLabel.Text = enum.Name
setAllSurfaces(demoPart, enum)
task.wait(1)
end
end

BottomSurfaceInput

Hidden
Deprecated
Read Parallel

The BottomSurfaceInput property determines the kind of input provided to a part's BasePart.BottomSurface. This is only relevant for Motor or SteppingMotor SurfaceTypes. This property determines how BasePart.BottomParamA and BasePart.BottomParamB are used. For brevity, these properties will be referred to as ParamA and ParamB, respectively.

  • By default, this is set to NoInput. This stops the motor altogether.
  • For Constant, the motor rotates at a constant velocity equal to ParamB.
  • For Sin, the motor rotates at a velocity equal to ParamA * math.sin(workspace.DistributedGameTime * ParamB). See Workspace.DistributedGameTime.

Code Samples

Motor Control

-- Paste this into a Script inside a part with a Motor SurfaceType
local partMotor = script.Parent
-- Place a brick called "MovingPart" so it is touching the Motor surface
-- For this example, we use TopSurface, TopSurfaceInput, TopParamA and TopParamB
-- However, this will work for all faces (NormalId): Top, Bottom, Left, Right, Front and Back
-- A function to quickly set all surface properties at once
local function setFaceSurfaceInputParams(normalId, surfaceType, inputType, paramA, paramB)
local surfaceName = normalId.Name -- e.g. "Top", "Bottom", etc
-- Syntax Note: in Lua, part.Something is the same as part["Something"]
-- The difference is that the latter allows us to use a string ("Something"), while
-- the former requires use of an identifier (.Something). Below, we build of each the surface
-- properties below by concatenating the surface name with the property postfix.
-- Set "___Surface", eg "TopSurface"
partMotor[surfaceName .. "Surface"] = surfaceType
-- Set "___SurfaceInput", eg "TopSurfaceInput"
partMotor[surfaceName .. "SurfaceInput"] = inputType
-- Set "___ParamA", eg "TopParamA"
partMotor[surfaceName .. "ParamA"] = paramA
-- Set "___ParamB", eg "TopParamB"
partMotor[surfaceName .. "ParamB"] = paramB
end
local normalId = Enum.NormalId.Top
while true do
-- Set to NoInput, where the motor will not operate at all
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.NoInput, 0, 0)
task.wait(1)
-- Set to Constant, where motor rotational velocity = paramB
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Constant, 0, 0.25)
task.wait(2)
-- Set to Sin, where motor rotational velocity = paramA * math.sin(time * paramB)
-- Since we're using pi (~3.14), the frequency of rotation is 1 second (per definition of sine function)
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Sin, 0.25, math.pi)
task.wait(3)
end

BrickColor

Not Replicated
Read Parallel

The BrickColor property determines the color of a part. If the part has a BasePart.Material, this also determines the color used when rendering the material texture. For more control over the color, the BasePart.Color property can be used (it is a Color3 variant of this property). If Color set, this property will use the closest BrickColor.

Other visual properties of a part are determined by BasePart.Transparency and BasePart.Reflectance.

Code Samples

This code sample will allow a part to be clicked to toggle its anchored property. When toggled, the visual appearance of the part is updated (red means anchored, yellow means free).

Part Anchored Toggle

local part = script.Parent
-- Create a ClickDetector so we can tell when the part is clicked
local cd = Instance.new("ClickDetector", part)
-- This function updates how the part looks based on its Anchored state
local function updateVisuals()
if part.Anchored then
-- When the part is anchored...
part.BrickColor = BrickColor.new("Bright red")
part.Material = Enum.Material.DiamondPlate
else
-- When the part is unanchored...
part.BrickColor = BrickColor.new("Bright yellow")
part.Material = Enum.Material.Wood
end
end
local function onToggle()
-- Toggle the anchored property
part.Anchored = not part.Anchored
-- Update visual state of the brick
updateVisuals()
end
-- Update, then start listening for clicks
updateVisuals()
cd.MouseClick:Connect(onToggle)

CFrame

Read Parallel

The CFrame property determines both the position and orientation of the BasePart in the world. It acts as an arbitrary reference location on the geometry, but ExtentsCFrame represents the actual CFrame of its physical center.

When setting CFrame on a part, other joined parts are also moved relative to the part, but it is recommended that you use PVInstance:PivotTo() to move an entire model, such as when teleporting a player's character.

Unlike setting BasePart.Position, setting BasePart.CFrame will always move the part to the exact given CFrame; in other words: no overlap checking is done and the physics solver will attempt to resolve any overlap unless both parts are Anchored.

For keeping track of positions relative to a part's CFrame, an Attachment may be useful.

Code Samples

This code sample demonstrates setting a part's CFrame in many different ways. It showcases how to create and compose CFrame values. It references a sibling part called "OtherPart" for demonstrating relative positioning.

Setting Part CFrame

local part = script.Parent:WaitForChild("Part")
local otherPart = script.Parent:WaitForChild("OtherPart")
-- Reset the part's CFrame to (0, 0, 0) with no rotation.
-- This is sometimes called the "identity" CFrame
part.CFrame = CFrame.new()
-- Set to a specific position (X, Y, Z)
part.CFrame = CFrame.new(0, 25, 10)
-- Same as above, but use a Vector3 instead
local point = Vector3.new(0, 25, 10)
part.CFrame = CFrame.new(point)
-- Set the part's CFrame to be at one point, looking at another
local lookAtPoint = Vector3.new(0, 20, 15)
part.CFrame = CFrame.lookAt(point, lookAtPoint)
-- Rotate the part's CFrame by pi/2 radians on local X axis
part.CFrame = part.CFrame * CFrame.Angles(math.pi / 2, 0, 0)
-- Rotate the part's CFrame by 45 degrees on local Y axis
part.CFrame = part.CFrame * CFrame.Angles(0, math.rad(45), 0)
-- Rotate the part's CFrame by 180 degrees on global Z axis (note the order!)
part.CFrame = CFrame.Angles(0, 0, math.pi) * part.CFrame -- Pi radians is equal to 180 degrees
-- Composing two CFrames is done using * (the multiplication operator)
part.CFrame = CFrame.new(2, 3, 4) * CFrame.new(4, 5, 6) --> equal to CFrame.new(6, 8, 10)
-- Unlike algebraic multiplication, CFrame composition is NOT communitative: a * b is not necessarily b * a!
-- Imagine * as an ORDERED series of actions. For example, the following lines produce different CFrames:
-- 1) Slide the part 5 units on X.
-- 2) Rotate the part 45 degrees around its Y axis.
part.CFrame = CFrame.new(5, 0, 0) * CFrame.Angles(0, math.rad(45), 0)
-- 1) Rotate the part 45 degrees around its Y axis.
-- 2) Slide the part 5 units on X.
part.CFrame = CFrame.Angles(0, math.rad(45), 0) * CFrame.new(5, 0, 0)
-- There is no "CFrame division", but instead simply "doing the inverse operation".
part.CFrame = CFrame.new(4, 5, 6) * CFrame.new(4, 5, 6):Inverse() --> is equal to CFrame.new(0, 0, 0)
part.CFrame = CFrame.Angles(0, 0, math.pi) * CFrame.Angles(0, 0, math.pi):Inverse() --> equal to CFrame.Angles(0, 0, 0)
-- Position a part relative to another (in this case, put our part on top of otherPart)
part.CFrame = otherPart.CFrame * CFrame.new(0, part.Size.Y / 2 + otherPart.Size.Y / 2, 0)

CanCollide

Read Parallel

CanCollide determines whether a part will physically interact with other parts. When disabled, other parts can pass through the brick uninterrupted. Parts used for decoration usually have CanCollide disabled, as they need not be considered by the physics engine.

If a part is not BasePart.Anchored and has CanCollide disabled, it may fall out of the world to be eventually destroyed by Workspace.FallenPartsDestroyHeight.

When CanCollide is disabled, parts may still fire the BasePart.Touched event (as well the other parts touching them). You can disable this with BasePart.CanTouch.

For more information on collisions, see Collisions.

Code Samples

This code sample shows how a part can fade away when touched by a Humanoid then reappear a moment after to create a passable door.

Fade Door

-- Paste into a Script inside a tall part
local part = script.Parent
local OPEN_TIME = 1
-- Can the door be opened at the moment?
local debounce = false
local function open()
part.CanCollide = false
part.Transparency = 0.7
part.BrickColor = BrickColor.new("Black")
end
local function close()
part.CanCollide = true
part.Transparency = 0
part.BrickColor = BrickColor.new("Bright blue")
end
local function onTouch(otherPart)
-- If the door was already open, do nothing
if debounce then
print("D")
return
end
-- Check if touched by a Humanoid
local human = otherPart.Parent:FindFirstChildOfClass("Humanoid")
if not human then
print("not human")
return
end
-- Perform the door opening sequence
debounce = true
open()
task.wait(OPEN_TIME)
close()
debounce = false
end
part.Touched:Connect(onTouch)
close()

CanQuery

Read Parallel

CanQuery determines whether the part is considered during spatial query operations, such as GetPartBoundsInBox or Raycast. CanCollide must also be disabled when disabling CanQuery. These functions will never include parts whose CanQuery and CanCollide is false.

Beyond this property, it is also possible to exclude parts which are descendants of a given list of parts using an OverlapParams or RaycastParams object when calling the spatial query functions.

CanTouch

Read Parallel

This property determines if Touched and TouchEnded events fire on the part. If true, other touching parts must also have CanTouch set to true for touch events to fire. If false, touch events cannot be set up for the part and attempting to do so will throw an error. Similarly, if the property is set to false after a touch event is connected, the event will be disconnected and the TouchTransmitter removed.

Note that this collision logic can be set to respect collision groups through the Workspace.TouchesUseCollisionGroups property. If true, parts in non-colliding groups will ignore both collisions and touch events, thereby making this property irrelevant.

Performance

There is a small performance gain on parts that have both CanTouch and CanCollide set to false, as these parts will never need to compute any kind of part to part collisions. However, they can still be hit by Raycasts and OverlapParams queries.

CastShadow

Read Parallel

Determines whether or not a part casts a shadow.

Note that this feature is not designed for performance enhancement. It should only be disabled on parts where you want to hide the shadows the part casts. Disabling this property for a given part may cause visual artifacts on the shadows cast upon that part.

CenterOfMass

Read Only
Not Replicated
Read Parallel

The CenterOfMass property describes the local position of a part's center of mass. If this is a single part assembly, this is the AssemblyCenterOfMass converted from world space to local. On simple Parts, the center of mass is always (0,0,0). It can vary for WedgePart or MeshPart however.

CollisionGroup

Not Replicated
Read Parallel

The CollisionGroup property describes the name of the part's collision group (maximum of 100 characters). Parts start off in the default group whose name is "Default". This value cannot be empty.

Although this property itself is non-replicated, the engine internally replicates the value through another private property to solve backward compatibility issues.

Code Samples

This example demonstrates one basic use of collision groups. It assigns BallPart to "CollisionGroupBall" and DoorPart to "CollisionGroupDoor", then makes the two groups non-collidable using PhysicsService:CollisionGroupSetCollidable().

PhysicsService:RegisterCollisionGroup

local PhysicsService = game:GetService("PhysicsService")
local collisionGroupBall = "CollisionGroupBall"
local collisionGroupDoor = "CollisionGroupDoor"
-- Register collision groups
PhysicsService:RegisterCollisionGroup(collisionGroupBall)
PhysicsService:RegisterCollisionGroup(collisionGroupDoor)
-- Assign parts to collision groups
script.Parent.BallPart.CollisionGroup = collisionGroupBall
script.Parent.DoorPart.CollisionGroup = collisionGroupDoor
-- Set groups as non-collidable with each other and check the result
PhysicsService:CollisionGroupSetCollidable(collisionGroupBall, collisionGroupDoor, false)
print(PhysicsService:CollisionGroupsAreCollidable(collisionGroupBall, collisionGroupDoor)) --> false

CollisionGroupId

Not Replicated
Deprecated
Read Parallel

The BasePart.CollisionGroupId property describes the ID number of the part's collision group. Parts start off in the "Default" group whose ID is 0. If a part is unregistered, the value becomes -1. This value cannot be less than -1 and it cannot exceed PhysicsService:GetMaxCollisionGroups(). Invalid IDs are clamped.

Although this property can be directly changed, it's recommended that you specify the collision group by setting BasePart.CollisionGroup to the collision group's name.

Color

Not Replicated
Read Parallel

The Color property determines the color of a part. If the part has a BasePart.Material, this also determines the color used when rendering the material texture. If this property is set, BasePart.BrickColor will use the closest BrickColor to the Color3 value.

Other visual properties of a part are determined by BasePart.Transparency and BasePart.Reflectance.

Code Samples

This code sample colors a player's entire character based on how much health they have. It generates a color based on their max health, then sets the color properties of objects within their character, removing any extra objects.

Character Health Body Color

-- Paste into a Script within StarterCharacterScripts
-- Then play the game, and fiddle with your character's health
local char = script.Parent
local human = char.Humanoid
local colorHealthy = Color3.new(0.4, 1, 0.2)
local colorUnhealthy = Color3.new(1, 0.4, 0.2)
local function setColor(color)
for _, child in pairs(char:GetChildren()) do
if child:IsA("BasePart") then
child.Color = color
while child:FindFirstChildOfClass("Decal") do
child:FindFirstChildOfClass("Decal"):Destroy()
end
elseif child:IsA("Accessory") then
child.Handle.Color = color
local mesh = child.Handle:FindFirstChildOfClass("SpecialMesh")
if mesh then
mesh.TextureId = ""
end
elseif child:IsA("Shirt") or child:IsA("Pants") then
child:Destroy()
end
end
end
local function update()
local percentage = human.Health / human.MaxHealth
-- Create a color by tweening based on the percentage of your health
-- The color goes from colorHealthy (100%) ----- > colorUnhealthy (0%)
local color = Color3.new(
colorHealthy.R * percentage + colorUnhealthy.r * (1 - percentage),
colorHealthy.G * percentage + colorUnhealthy.g * (1 - percentage),
colorHealthy.B * percentage + colorUnhealthy.b * (1 - percentage)
)
setColor(color)
end
update()
human.HealthChanged:Connect(update)

CurrentPhysicalProperties

Read Only
Not Replicated
Read Parallel

CurrentPhysicalProperties indicates the current physical properties of the part. You can set custom values for the physical properties per part, custom material, and material override. The Engine prioritizes more granular definitions when determining the effective physical properties of a part. The values in the following list are in order from highest to lowest priority:

  • Custom physical properties of the part
  • Custom physical properties of the part's custom material
  • Custom physical properties of the material override of the part's material
  • Default physical properties of the part's material

CustomPhysicalProperties

Read Parallel

CustomPhysicalProperties lets you customize various physical aspects of a Part, such as its density, friction, and elasticity.

If enabled, this property let's you configure these physical properties. If disabled, these physical properties are determined by the BasePart.Material of the part. The page for Enum.Material contains list of the various part materials.

Code Samples

This code sample demonstrates how to set the CustomPhysicalProperties property of a part.

Set CustomPhysicalProperties

local part = script.Parent
-- This will make the part light and bouncy!
local DENSITY = 0.3
local FRICTION = 0.1
local ELASTICITY = 1
local FRICTION_WEIGHT = 1
local ELASTICITY_WEIGHT = 1
local physProperties = PhysicalProperties.new(DENSITY, FRICTION, ELASTICITY, FRICTION_WEIGHT, ELASTICITY_WEIGHT)
part.CustomPhysicalProperties = physProperties

Elasticity

Hidden
Not Replicated
Deprecated
Read Parallel

The Elasticity of a part is now determined by either its Enum.Material or its CustomPhysicalProperties.

EnableFluidForces

Read Parallel

When true, and when Workspace.FluidForces is enabled, causes the physics engine to compute aerodynamic forces on this BasePart.

ExtentsCFrame

Read Only
Not Replicated
Read Parallel

The CFrame of the physical extents of the BasePart, representing its physical center.

ExtentsSize

Read Only
Not Replicated
Read Parallel

The actual physical size of the BasePart as regarded by the physics engine, for example in collision detection.

Friction

Hidden
Not Replicated
Deprecated
Read Parallel

Used to control the Friction of the part, but now it no longer does anything. The Friction of a part is now determined by either its Material or its CustomPhysicalProperties.

FrontParamA

Hidden
Deprecated
Read Parallel

The FrontParamA property is relevant when a part's BasePart.FrontSurface is set to Motor or SteppingMotor and BasePart.FrontSurfaceInput is set to Sin. It determines the amplitude of the motor's rotational velocity, using the following formula:

MotorVelocity = ParamA * math.sin(workspace.DistributedGameTime * ParamB)

In no other cases is this property used.

Code Samples

Motor Control

-- Paste this into a Script inside a part with a Motor SurfaceType
local partMotor = script.Parent
-- Place a brick called "MovingPart" so it is touching the Motor surface
-- For this example, we use TopSurface, TopSurfaceInput, TopParamA and TopParamB
-- However, this will work for all faces (NormalId): Top, Bottom, Left, Right, Front and Back
-- A function to quickly set all surface properties at once
local function setFaceSurfaceInputParams(normalId, surfaceType, inputType, paramA, paramB)
local surfaceName = normalId.Name -- e.g. "Top", "Bottom", etc
-- Syntax Note: in Lua, part.Something is the same as part["Something"]
-- The difference is that the latter allows us to use a string ("Something"), while
-- the former requires use of an identifier (.Something). Below, we build of each the surface
-- properties below by concatenating the surface name with the property postfix.
-- Set "___Surface", eg "TopSurface"
partMotor[surfaceName .. "Surface"] = surfaceType
-- Set "___SurfaceInput", eg "TopSurfaceInput"
partMotor[surfaceName .. "SurfaceInput"] = inputType
-- Set "___ParamA", eg "TopParamA"
partMotor[surfaceName .. "ParamA"] = paramA
-- Set "___ParamB", eg "TopParamB"
partMotor[surfaceName .. "ParamB"] = paramB
end
local normalId = Enum.NormalId.Top
while true do
-- Set to NoInput, where the motor will not operate at all
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.NoInput, 0, 0)
task.wait(1)
-- Set to Constant, where motor rotational velocity = paramB
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Constant, 0, 0.25)
task.wait(2)
-- Set to Sin, where motor rotational velocity = paramA * math.sin(time * paramB)
-- Since we're using pi (~3.14), the frequency of rotation is 1 second (per definition of sine function)
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Sin, 0.25, math.pi)
task.wait(3)
end

FrontParamB

Hidden
Deprecated
Read Parallel

The FrontParamB property is relevant when a part's BasePart.FrontSurface is set to Motor or SteppingMotor and BasePart.FrontSurfaceInput is set to Constant or Sin. For Constant, it determines the constant rotational velocity of the motor. For Sin, it determines the frequency of the motor's rotational velocity, using the following formula:

MotorVelocity = ParamB * math.sin(workspace.DistributedGameTime * ParamB)

In no other cases is this property used.

Code Samples

Motor Control

-- Paste this into a Script inside a part with a Motor SurfaceType
local partMotor = script.Parent
-- Place a brick called "MovingPart" so it is touching the Motor surface
-- For this example, we use TopSurface, TopSurfaceInput, TopParamA and TopParamB
-- However, this will work for all faces (NormalId): Top, Bottom, Left, Right, Front and Back
-- A function to quickly set all surface properties at once
local function setFaceSurfaceInputParams(normalId, surfaceType, inputType, paramA, paramB)
local surfaceName = normalId.Name -- e.g. "Top", "Bottom", etc
-- Syntax Note: in Lua, part.Something is the same as part["Something"]
-- The difference is that the latter allows us to use a string ("Something"), while
-- the former requires use of an identifier (.Something). Below, we build of each the surface
-- properties below by concatenating the surface name with the property postfix.
-- Set "___Surface", eg "TopSurface"
partMotor[surfaceName .. "Surface"] = surfaceType
-- Set "___SurfaceInput", eg "TopSurfaceInput"
partMotor[surfaceName .. "SurfaceInput"] = inputType
-- Set "___ParamA", eg "TopParamA"
partMotor[surfaceName .. "ParamA"] = paramA
-- Set "___ParamB", eg "TopParamB"
partMotor[surfaceName .. "ParamB"] = paramB
end
local normalId = Enum.NormalId.Top
while true do
-- Set to NoInput, where the motor will not operate at all
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.NoInput, 0, 0)
task.wait(1)
-- Set to Constant, where motor rotational velocity = paramB
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Constant, 0, 0.25)
task.wait(2)
-- Set to Sin, where motor rotational velocity = paramA * math.sin(time * paramB)
-- Since we're using pi (~3.14), the frequency of rotation is 1 second (per definition of sine function)
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Sin, 0.25, math.pi)
task.wait(3)
end

FrontSurface

Read Parallel

The FrontSurface property determines the type of surface used for the -Z direction of a part. When two parts' faces are placed next to each other, they may create a joint between them. If set to Motor, the BasePart.FrontSurfaceInput determines how a motor joint should behave.

Most SurfaceTypes render a texture on the part face if the BasePart.Material is set to Plastic. Some SurfaceTypes including Hinge, Motor, and SteppingMotor render a 3D adornment instead. If this property is selected in the Properties window, it will be highlighted in the game world similar to that of a SurfaceSelection.

Code Samples

This code sample shows what each SurfaceType looks like on a part. In addition, it creates a BillboardGui label on the part with a TextLabel that reflects the name of the current SurfaceType.

Show All SurfaceTypes

local demoPart = script.Parent
-- Create a billboard gui to display what the current surface type is
local billboard = Instance.new("BillboardGui")
billboard.AlwaysOnTop = true
billboard.Size = UDim2.new(0, 200, 0, 50)
billboard.Adornee = demoPart
local textLabel = Instance.new("TextLabel")
textLabel.Size = UDim2.new(0, 200, 0, 50)
textLabel.BackgroundTransparency = 1
textLabel.TextStrokeTransparency = 0
textLabel.TextColor3 = Color3.new(1, 1, 1) -- White
textLabel.Parent = billboard
billboard.Parent = demoPart
local function setAllSurfaces(part, surfaceType)
part.TopSurface = surfaceType
part.BottomSurface = surfaceType
part.LeftSurface = surfaceType
part.RightSurface = surfaceType
part.FrontSurface = surfaceType
part.BackSurface = surfaceType
end
while true do
-- Iterate through the different SurfaceTypes
for _, enum in pairs(Enum.SurfaceType:GetEnumItems()) do
textLabel.Text = enum.Name
setAllSurfaces(demoPart, enum)
task.wait(1)
end
end

FrontSurfaceInput

Hidden
Deprecated
Read Parallel

The FrontSurfaceInput property determines the kind of input provided to a part's BasePart.FrontSurface. This is only relevant for Motor or SteppingMotor SurfaceTypes. This property determines how BasePart.FrontParamA and BasePart.FrontParamB are used. For brevity, these properties will be referred to as ParamA and ParamB, respectively.

  • By default, this is set to NoInput. This stops the motor altogether.
  • For Constant, the motor rotates at a constant velocity equal to ParamB.
  • For Sin, the motor rotates at a velocity equal to ParamA * math.sin(workspace.DistributedGameTime * ParamB). See Workspace.DistributedGameTime.

Code Samples

Motor Control

-- Paste this into a Script inside a part with a Motor SurfaceType
local partMotor = script.Parent
-- Place a brick called "MovingPart" so it is touching the Motor surface
-- For this example, we use TopSurface, TopSurfaceInput, TopParamA and TopParamB
-- However, this will work for all faces (NormalId): Top, Bottom, Left, Right, Front and Back
-- A function to quickly set all surface properties at once
local function setFaceSurfaceInputParams(normalId, surfaceType, inputType, paramA, paramB)
local surfaceName = normalId.Name -- e.g. "Top", "Bottom", etc
-- Syntax Note: in Lua, part.Something is the same as part["Something"]
-- The difference is that the latter allows us to use a string ("Something"), while
-- the former requires use of an identifier (.Something). Below, we build of each the surface
-- properties below by concatenating the surface name with the property postfix.
-- Set "___Surface", eg "TopSurface"
partMotor[surfaceName .. "Surface"] = surfaceType
-- Set "___SurfaceInput", eg "TopSurfaceInput"
partMotor[surfaceName .. "SurfaceInput"] = inputType
-- Set "___ParamA", eg "TopParamA"
partMotor[surfaceName .. "ParamA"] = paramA
-- Set "___ParamB", eg "TopParamB"
partMotor[surfaceName .. "ParamB"] = paramB
end
local normalId = Enum.NormalId.Top
while true do
-- Set to NoInput, where the motor will not operate at all
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.NoInput, 0, 0)
task.wait(1)
-- Set to Constant, where motor rotational velocity = paramB
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Constant, 0, 0.25)
task.wait(2)
-- Set to Sin, where motor rotational velocity = paramA * math.sin(time * paramB)
-- Since we're using pi (~3.14), the frequency of rotation is 1 second (per definition of sine function)
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Sin, 0.25, math.pi)
task.wait(3)
end

LeftParamA

Hidden
Deprecated
Read Parallel

The LeftParamA property is relevant when a part's BasePart.LeftSurface is set to Motor or SteppingMotor and BasePart.LeftSurfaceInput is set to Sin. It determines the amplitude of the motor's rotational velocity, using the following formula:

MotorVelocity = ParamA * math.sin(workspace.DistributedGameTime * ParamB)

In no other cases is this property used.

Code Samples

Motor Control

-- Paste this into a Script inside a part with a Motor SurfaceType
local partMotor = script.Parent
-- Place a brick called "MovingPart" so it is touching the Motor surface
-- For this example, we use TopSurface, TopSurfaceInput, TopParamA and TopParamB
-- However, this will work for all faces (NormalId): Top, Bottom, Left, Right, Front and Back
-- A function to quickly set all surface properties at once
local function setFaceSurfaceInputParams(normalId, surfaceType, inputType, paramA, paramB)
local surfaceName = normalId.Name -- e.g. "Top", "Bottom", etc
-- Syntax Note: in Lua, part.Something is the same as part["Something"]
-- The difference is that the latter allows us to use a string ("Something"), while
-- the former requires use of an identifier (.Something). Below, we build of each the surface
-- properties below by concatenating the surface name with the property postfix.
-- Set "___Surface", eg "TopSurface"
partMotor[surfaceName .. "Surface"] = surfaceType
-- Set "___SurfaceInput", eg "TopSurfaceInput"
partMotor[surfaceName .. "SurfaceInput"] = inputType
-- Set "___ParamA", eg "TopParamA"
partMotor[surfaceName .. "ParamA"] = paramA
-- Set "___ParamB", eg "TopParamB"
partMotor[surfaceName .. "ParamB"] = paramB
end
local normalId = Enum.NormalId.Top
while true do
-- Set to NoInput, where the motor will not operate at all
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.NoInput, 0, 0)
task.wait(1)
-- Set to Constant, where motor rotational velocity = paramB
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Constant, 0, 0.25)
task.wait(2)
-- Set to Sin, where motor rotational velocity = paramA * math.sin(time * paramB)
-- Since we're using pi (~3.14), the frequency of rotation is 1 second (per definition of sine function)
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Sin, 0.25, math.pi)
task.wait(3)
end

LeftParamB

Hidden
Deprecated
Read Parallel

The LeftParamB property is relevant when a part's BasePart.LeftSurface is set to Motor or SteppingMotor and BasePart.LeftSurfaceInput is set to Constant or Sin. For Constant, it determines the constant rotational velocity of the motor. For Sin, it determines the frequency of the motor's rotational velocity, using the following formula:

MotorVelocity = ParamB * math.sin(workspace.DistributedGameTime * ParamB)

In no other cases is this property used.

Code Samples

Motor Control

-- Paste this into a Script inside a part with a Motor SurfaceType
local partMotor = script.Parent
-- Place a brick called "MovingPart" so it is touching the Motor surface
-- For this example, we use TopSurface, TopSurfaceInput, TopParamA and TopParamB
-- However, this will work for all faces (NormalId): Top, Bottom, Left, Right, Front and Back
-- A function to quickly set all surface properties at once
local function setFaceSurfaceInputParams(normalId, surfaceType, inputType, paramA, paramB)
local surfaceName = normalId.Name -- e.g. "Top", "Bottom", etc
-- Syntax Note: in Lua, part.Something is the same as part["Something"]
-- The difference is that the latter allows us to use a string ("Something"), while
-- the former requires use of an identifier (.Something). Below, we build of each the surface
-- properties below by concatenating the surface name with the property postfix.
-- Set "___Surface", eg "TopSurface"
partMotor[surfaceName .. "Surface"] = surfaceType
-- Set "___SurfaceInput", eg "TopSurfaceInput"
partMotor[surfaceName .. "SurfaceInput"] = inputType
-- Set "___ParamA", eg "TopParamA"
partMotor[surfaceName .. "ParamA"] = paramA
-- Set "___ParamB", eg "TopParamB"
partMotor[surfaceName .. "ParamB"] = paramB
end
local normalId = Enum.NormalId.Top
while true do
-- Set to NoInput, where the motor will not operate at all
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.NoInput, 0, 0)
task.wait(1)
-- Set to Constant, where motor rotational velocity = paramB
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Constant, 0, 0.25)
task.wait(2)
-- Set to Sin, where motor rotational velocity = paramA * math.sin(time * paramB)
-- Since we're using pi (~3.14), the frequency of rotation is 1 second (per definition of sine function)
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Sin, 0.25, math.pi)
task.wait(3)
end

LeftSurface

Read Parallel

The LeftSurface property determines the type of surface used for the -X direction of a part. When two parts' faces are placed next to each other, they may create a joint between them. If set to Motor, the BasePart.LeftSurfaceInput determines how a motor joint should behave.

Most SurfaceTypes render a texture on the part face if the BasePart.Material is set to Plastic. Some SurfaceTypes including Hinge, Motor, and SteppingMotor render a 3D adornment instead. If this property is selected in the Properties window, it will be highlighted in the game world similar to that of a SurfaceSelection.

Code Samples

This code sample shows what each SurfaceType looks like on a part. In addition, it creates a BillboardGui label on the part with a TextLabel that reflects the name of the current SurfaceType.

Show All SurfaceTypes

local demoPart = script.Parent
-- Create a billboard gui to display what the current surface type is
local billboard = Instance.new("BillboardGui")
billboard.AlwaysOnTop = true
billboard.Size = UDim2.new(0, 200, 0, 50)
billboard.Adornee = demoPart
local textLabel = Instance.new("TextLabel")
textLabel.Size = UDim2.new(0, 200, 0, 50)
textLabel.BackgroundTransparency = 1
textLabel.TextStrokeTransparency = 0
textLabel.TextColor3 = Color3.new(1, 1, 1) -- White
textLabel.Parent = billboard
billboard.Parent = demoPart
local function setAllSurfaces(part, surfaceType)
part.TopSurface = surfaceType
part.BottomSurface = surfaceType
part.LeftSurface = surfaceType
part.RightSurface = surfaceType
part.FrontSurface = surfaceType
part.BackSurface = surfaceType
end
while true do
-- Iterate through the different SurfaceTypes
for _, enum in pairs(Enum.SurfaceType:GetEnumItems()) do
textLabel.Text = enum.Name
setAllSurfaces(demoPart, enum)
task.wait(1)
end
end

LeftSurfaceInput

Hidden
Deprecated
Read Parallel

The LeftSurfaceInput property determines the kind of input provided to a part's BasePart.LeftSurface. This is only relevant for Motor or SteppingMotor SurfaceTypes. This property determines how BasePart.LeftParamA and BasePart.LeftParamB are used. For brevity, these properties will be referred to as ParamA and ParamB, respectively.

  • By default, this is set to NoInput. This stops the motor altogether.
  • For Constant, the motor rotates at a constant velocity equal to ParamB.
  • For Sin, the motor rotates at a velocity equal to ParamA * math.sin(workspace.DistributedGameTime * ParamB). See Workspace.DistributedGameTime.

Code Samples

Motor Control

-- Paste this into a Script inside a part with a Motor SurfaceType
local partMotor = script.Parent
-- Place a brick called "MovingPart" so it is touching the Motor surface
-- For this example, we use TopSurface, TopSurfaceInput, TopParamA and TopParamB
-- However, this will work for all faces (NormalId): Top, Bottom, Left, Right, Front and Back
-- A function to quickly set all surface properties at once
local function setFaceSurfaceInputParams(normalId, surfaceType, inputType, paramA, paramB)
local surfaceName = normalId.Name -- e.g. "Top", "Bottom", etc
-- Syntax Note: in Lua, part.Something is the same as part["Something"]
-- The difference is that the latter allows us to use a string ("Something"), while
-- the former requires use of an identifier (.Something). Below, we build of each the surface
-- properties below by concatenating the surface name with the property postfix.
-- Set "___Surface", eg "TopSurface"
partMotor[surfaceName .. "Surface"] = surfaceType
-- Set "___SurfaceInput", eg "TopSurfaceInput"
partMotor[surfaceName .. "SurfaceInput"] = inputType
-- Set "___ParamA", eg "TopParamA"
partMotor[surfaceName .. "ParamA"] = paramA
-- Set "___ParamB", eg "TopParamB"
partMotor[surfaceName .. "ParamB"] = paramB
end
local normalId = Enum.NormalId.Top
while true do
-- Set to NoInput, where the motor will not operate at all
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.NoInput, 0, 0)
task.wait(1)
-- Set to Constant, where motor rotational velocity = paramB
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Constant, 0, 0.25)
task.wait(2)
-- Set to Sin, where motor rotational velocity = paramA * math.sin(time * paramB)
-- Since we're using pi (~3.14), the frequency of rotation is 1 second (per definition of sine function)
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Sin, 0.25, math.pi)
task.wait(3)
end

LocalTransparencyModifier

Hidden
Not Replicated
Read Parallel

The LocalTransparencyModifier property is a multiplier to BasePart.Transparency that is only visible to the local client. It does not replicate from client to server and is useful for when a part should not render for a specific client, such as how the player does not see their character's body parts when they zoom into first person mode.

This property modifies the local part's transparency through the following formula, with resulting values clamped between 0 and 1.


clientTransparency = 1 - ((1 - part.Transparency) * (1 - part.LocalTransparencyModifier))
TransparencyLocalTransparencyModifierServer-Side TransparencyClient-Side Transparency
0.500.50.5
0.50.250.50.625
0.50.50.50.75
0.50.750.50.875
0.510.51

Locked

Read Parallel

The Locked property determines whether a part (or a model it is contained within) may be selected in Roblox Studio by clicking on it. This property is most often enabled on parts within environment models that aren't being edited at the moment. Roblox Studio has a Lock/Unlock All tool that can toggle the Locked state of every part descendant in a model at once.

Code Samples

This code sample uses the concept of recursion to unlock all parts that are a descendant of a model.

Recursive Unlock

-- Paste into a Script within a Model you want to unlock
local model = script.Parent
-- This function recurses through a model's heirarchy and unlocks
-- every part that it encounters.
local function recursiveUnlock(object)
if object:IsA("BasePart") then
object.Locked = false
end
-- Call the same function on the children of the object
-- The recursive process stops if an object has no children
for _, child in pairs(object:GetChildren()) do
recursiveUnlock(child)
end
end
recursiveUnlock(model)

Mass

Read Only
Not Replicated
Read Parallel

Mass is a read-only property that describes the product of a part's volume and density. It is returned by the GetMass function.

Massless

Read Parallel

If this property is enabled, the BasePart will not contribute to the total mass or inertia of its assembly as long as it is welded to another part that has mass.

If the part is its own root part according to AssemblyRootPart, this will be ignored for that part, and it will still contribute mass and inertia to its assembly like a normal part. Parts that are massless should never become an assembly root part unless all other parts in the assembly are also massless.

This might be useful for things like optional accessories on vehicles that you don't want to affect the handling of the car or a massless render mesh welded to a simpler collision mesh.

See also Assemblies, an article documenting what root parts are and how to use them.

Read Parallel

The Material property allows a builder to set a part's texture and default physical properties (in the case that BasePart.CustomPhysicalProperties is unset). The default Plastic material has a very light texture, and the SmoothPlastic material has no texture at all. Some material textures like DiamondPlate and Granite have very visible textures. Each material's texture reflects sunlight differently, especially Foil.

Setting this property then enabling BasePart.CustomPhysicalProperties will use the default physical properties of a material. For instance, DiamondPlate is a very dense material while Wood is very light. A part's density determines whether it will float in terrain water.

The Glass material changes rendering behavior on moderate graphics settings. It applies a bit of reflectiveness (similar to BasePart.Reflectance) and perspective distortion. The effect is especially pronounced on sphere-shaped parts (set BasePart.Shape to Ball). Semitransparent objects and Glass parts behind Glass are not visible.

Code Samples

This code sample will allow a part to be clicked to toggle its anchored property. When toggled, the visual appearance of the part is updated (red means anchored, yellow means free).

Part Anchored Toggle

local part = script.Parent
-- Create a ClickDetector so we can tell when the part is clicked
local cd = Instance.new("ClickDetector", part)
-- This function updates how the part looks based on its Anchored state
local function updateVisuals()
if part.Anchored then
-- When the part is anchored...
part.BrickColor = BrickColor.new("Bright red")
part.Material = Enum.Material.DiamondPlate
else
-- When the part is unanchored...
part.BrickColor = BrickColor.new("Bright yellow")
part.Material = Enum.Material.Wood
end
end
local function onToggle()
-- Toggle the anchored property
part.Anchored = not part.Anchored
-- Update visual state of the brick
updateVisuals()
end
-- Update, then start listening for clicks
updateVisuals()
cd.MouseClick:Connect(onToggle)

MaterialVariant

Not Replicated
Read Parallel

The system searches the MaterialVariant instance with specified MaterialVariant name and BasePart.Material type. If it successfully finds a matching MaterialVariant instance, it uses this MaterialVariant instance to replace the default material. Default material can be the built-in material or an override MaterialVariant specified in MaterialService.

Orientation

Hidden
Not Replicated
Read Parallel

The Orientation property describes the part's rotation in degrees around the X, Y and Z axes using a Vector3. The rotations are applied in Y → X → Z order. This differs from proper Euler angles and is instead Tait-Bryan angles, which describe yaw, pitch and roll. It is also worth noting how this property differs from the CFrame.Angles() constructor, which applies rotations in a different order (Z → Y → X). For better control over the rotation of a part, it is recommended that BasePart.CFrame is set instead.

When setting this property any Welds or Motor6Ds connected to this part will have the matching C0 or C1 property updated and to allow the part to move relative to any other parts it is joined to.

WeldConstraints will also be temporarily disabled and re-enabled during the move.

Code Samples

This code sample rotates a part continually on the Y axis.

Part Spinner

local part = script.Parent
local INCREMENT = 360 / 20
-- Rotate the part continually
while true do
for degrees = 0, 360, INCREMENT do
-- Set only the Y axis rotation
part.Rotation = Vector3.new(0, degrees, 0)
-- A better way to do this would be setting CFrame
--part.CFrame = CFrame.new(part.Position) * CFrame.Angles(0, math.rad(degrees), 0)
task.wait()
end
end

PivotOffset

Read Parallel

This property specifies the offset of the part's pivot from its CFrame, that is part:GetPivot() is the same as part.CFrame * part.PivotOffset.

This is convenient for setting the pivot to a location in local space, but setting a part's pivot to a location in world space can be done as follows:


local Workspace = game:GetService("Workspace")
local part = Workspace.BluePart
local desiredPivotCFrameInWorldSpace = CFrame.new(0, 10, 0)
part.PivotOffset = part.CFrame:ToObjectSpace(desiredPivotCFrameInWorldSpace)

Code Samples

This code sample shows a custom function for resetting the pivot of a model back to the center of that model's bounding box.

Reset Pivot

local function resetPivot(model)
local boundsCFrame = model:GetBoundingBox()
if model.PrimaryPart then
model.PrimaryPart.PivotOffset = model.PrimaryPart.CFrame:ToObjectSpace(boundsCFrame)
else
model.WorldPivot = boundsCFrame
end
end
resetPivot(script.Parent)

This code sample creates a clock at the origin with a minute, second, and hour hand, and makes it tick, displaying the local time.

Clock Hands

local function createHand(length, width, yOffset)
local part = Instance.new("Part")
part.Size = Vector3.new(width, 0.1, length)
part.Material = Enum.Material.Neon
part.PivotOffset = CFrame.new(0, -(yOffset + 0.1), length / 2)
part.Anchored = true
part.Parent = workspace
return part
end
local function positionHand(hand, fraction)
hand:PivotTo(CFrame.fromEulerAnglesXYZ(0, -fraction * 2 * math.pi, 0))
end
-- Create dial
for i = 0, 11 do
local dialPart = Instance.new("Part")
dialPart.Size = Vector3.new(0.2, 0.2, 1)
dialPart.TopSurface = Enum.SurfaceType.Smooth
if i == 0 then
dialPart.Size = Vector3.new(0.2, 0.2, 2)
dialPart.Color = Color3.new(1, 0, 0)
end
dialPart.PivotOffset = CFrame.new(0, -0.1, 10.5)
dialPart.Anchored = true
dialPart:PivotTo(CFrame.fromEulerAnglesXYZ(0, (i / 12) * 2 * math.pi, 0))
dialPart.Parent = workspace
end
-- Create hands
local hourHand = createHand(7, 1, 0)
local minuteHand = createHand(10, 0.6, 0.1)
local secondHand = createHand(11, 0.2, 0.2)
-- Run clock
while true do
local components = os.date("*t")
positionHand(hourHand, (components.hour + components.min / 60) / 12)
positionHand(minuteHand, (components.min + components.sec / 60) / 60)
positionHand(secondHand, components.sec / 60)
task.wait()
end

Position

Hidden
Not Replicated
Read Parallel

The Position property describes the coordinates of a part using a Vector3. It reflects the position of the part's BasePart.CFrame, however it can also be set.

When setting this property any Welds or Motor6Ds connected to this part will have the matching C0 or C1 property updated and to allow the part to move relative to any other parts it is joined to.

WeldConstraints will also be temporarily disabled and re-enabled during the move.

ReceiveAge

Hidden
Read Only
Not Replicated
Read Parallel

This returns the time in seconds since the part's physics got last updated on the local client (or the server). Returns 0 when the part has no physics (Anchored)

Reflectance

Read Parallel

The Reflectance property determines how much a part reflects the skybox. A value of 0 indicates the part is not reflective at all, and a value of 1 indicates the part should fully reflect.

Reflectance is not affected by BasePart.Transparency, unless the part is fully transparent, in which case reflectance will not render at all. Reflectance may or may not be ignored depending on the BasePart.Material of the part.

Code Samples

This code sample causes a part to blink its Reflectance and a PointLight every time it is touched. It uses a pattern that prevents multiple concurrent function calls from fighting with each other.

Touch Blink

local part = script.Parent
local pointLight = Instance.new("PointLight")
pointLight.Brightness = 0
pointLight.Range = 12
pointLight.Parent = part
local touchNo = 0
local function blink()
-- Advance touchNo to tell other blink() calls to stop early
touchNo = touchNo + 1
-- Save touchNo locally so we can tell when it changes globally
local myTouchNo = touchNo
for i = 1, 0, -0.1 do
-- Stop early if another blink started
if touchNo ~= myTouchNo then
break
end
-- Update the blink animation
part.Reflectance = i
pointLight.Brightness = i * 2
task.wait(0.05)
end
end
part.Touched:Connect(blink)

ResizeIncrement

Read Only
Not Replicated
Read Parallel

The ResizeIncrement property is a read-only property that describes the smallest change in size allowable by the BasePart:Resize() method. It differs between implementations of the BasePart abstract class. For instance, Part has this set to 1 and TrussPart has this set to 2 (since individual truss sections are 2x2x2 in size).

Code Samples

This code sample creates a Handles object and shows how to set the Faces property of the object. It also references ResizeableFaces of a part. Try placing this script in multiple kinds of parts to see how ResizeableFaces varies.

Resize Handles

-- Put this Script in several kinds of BasePart, like
-- Part, TrussPart, WedgePart, CornerWedgePart, etc.
local part = script.Parent
-- Create a handles object for this part
local handles = Instance.new("Handles")
handles.Adornee = part
handles.Parent = part
-- Manually specify the faces applicable for this handle
handles.Faces = Faces.new(Enum.NormalId.Top, Enum.NormalId.Front, Enum.NormalId.Left)
-- Alternatively, use the faces on which the part can be resized.
-- If part is a TrussPart with only two Size dimensions
-- of length 2, then ResizeableFaces will only have two
-- enabled faces. For other parts, all faces will be enabled.
handles.Faces = part.ResizeableFaces

ResizeableFaces

Read Only
Not Replicated
Read Parallel

The ResizeableFaces property (with an e, not ResizableFaces) describes using a Faces object the different faces on which a part may be resized. For most implementations of BasePart, such as Part and WedgePart, this property includes all faces. However, TrussPart will set its ResizeableFaces set to only two faces since those kinds of parts must have two BasePart.Size dimensions of length 2. This property is most commonly used with tools used for building and manipulating parts and has little use outside of that context. The Handles class, which has the Handles.Faces property, can be used in conjunction with this property to display only the handles on faces that can be resized on a part.

Code Samples

This code sample creates a Handles object and shows how to set the Faces property of the object. It also references ResizeableFaces of a part. Try placing this script in multiple kinds of parts to see how ResizeableFaces varies.

Resize Handles

-- Put this Script in several kinds of BasePart, like
-- Part, TrussPart, WedgePart, CornerWedgePart, etc.
local part = script.Parent
-- Create a handles object for this part
local handles = Instance.new("Handles")
handles.Adornee = part
handles.Parent = part
-- Manually specify the faces applicable for this handle
handles.Faces = Faces.new(Enum.NormalId.Top, Enum.NormalId.Front, Enum.NormalId.Left)
-- Alternatively, use the faces on which the part can be resized.
-- If part is a TrussPart with only two Size dimensions
-- of length 2, then ResizeableFaces will only have two
-- enabled faces. For other parts, all faces will be enabled.
handles.Faces = part.ResizeableFaces

RightParamA

Hidden
Deprecated
Read Parallel

The RightParamA property is relevant when a part's BasePart.RightSurface is set to Motor or SteppingMotor and BasePart.RightSurfaceInput is set to Sin. It determines the amplitude of the motor's rotational velocity, using the following formula:

MotorVelocity = ParamA * math.sin(workspace.DistributedGameTime * ParamB)

In no other cases is this property used.

Code Samples

Motor Control

-- Paste this into a Script inside a part with a Motor SurfaceType
local partMotor = script.Parent
-- Place a brick called "MovingPart" so it is touching the Motor surface
-- For this example, we use TopSurface, TopSurfaceInput, TopParamA and TopParamB
-- However, this will work for all faces (NormalId): Top, Bottom, Left, Right, Front and Back
-- A function to quickly set all surface properties at once
local function setFaceSurfaceInputParams(normalId, surfaceType, inputType, paramA, paramB)
local surfaceName = normalId.Name -- e.g. "Top", "Bottom", etc
-- Syntax Note: in Lua, part.Something is the same as part["Something"]
-- The difference is that the latter allows us to use a string ("Something"), while
-- the former requires use of an identifier (.Something). Below, we build of each the surface
-- properties below by concatenating the surface name with the property postfix.
-- Set "___Surface", eg "TopSurface"
partMotor[surfaceName .. "Surface"] = surfaceType
-- Set "___SurfaceInput", eg "TopSurfaceInput"
partMotor[surfaceName .. "SurfaceInput"] = inputType
-- Set "___ParamA", eg "TopParamA"
partMotor[surfaceName .. "ParamA"] = paramA
-- Set "___ParamB", eg "TopParamB"
partMotor[surfaceName .. "ParamB"] = paramB
end
local normalId = Enum.NormalId.Top
while true do
-- Set to NoInput, where the motor will not operate at all
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.NoInput, 0, 0)
task.wait(1)
-- Set to Constant, where motor rotational velocity = paramB
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Constant, 0, 0.25)
task.wait(2)
-- Set to Sin, where motor rotational velocity = paramA * math.sin(time * paramB)
-- Since we're using pi (~3.14), the frequency of rotation is 1 second (per definition of sine function)
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Sin, 0.25, math.pi)
task.wait(3)
end

RightParamB

Hidden
Deprecated
Read Parallel

The RightParamB property is relevant when a part's BasePart.RightSurface is set to Motor or SteppingMotor and BasePart.RightSurfaceInput is set to Constant or Sin. For Constant, it determines the constant rotational velocity of the motor. For Sin, it determines the frequency of the motor's rotational velocity, using the following formula:

MotorVelocity = ParamB * math.sin(workspace.DistributedGameTime * ParamB)

In no other cases is this property used.

Code Samples

Motor Control

-- Paste this into a Script inside a part with a Motor SurfaceType
local partMotor = script.Parent
-- Place a brick called "MovingPart" so it is touching the Motor surface
-- For this example, we use TopSurface, TopSurfaceInput, TopParamA and TopParamB
-- However, this will work for all faces (NormalId): Top, Bottom, Left, Right, Front and Back
-- A function to quickly set all surface properties at once
local function setFaceSurfaceInputParams(normalId, surfaceType, inputType, paramA, paramB)
local surfaceName = normalId.Name -- e.g. "Top", "Bottom", etc
-- Syntax Note: in Lua, part.Something is the same as part["Something"]
-- The difference is that the latter allows us to use a string ("Something"), while
-- the former requires use of an identifier (.Something). Below, we build of each the surface
-- properties below by concatenating the surface name with the property postfix.
-- Set "___Surface", eg "TopSurface"
partMotor[surfaceName .. "Surface"] = surfaceType
-- Set "___SurfaceInput", eg "TopSurfaceInput"
partMotor[surfaceName .. "SurfaceInput"] = inputType
-- Set "___ParamA", eg "TopParamA"
partMotor[surfaceName .. "ParamA"] = paramA
-- Set "___ParamB", eg "TopParamB"
partMotor[surfaceName .. "ParamB"] = paramB
end
local normalId = Enum.NormalId.Top
while true do
-- Set to NoInput, where the motor will not operate at all
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.NoInput, 0, 0)
task.wait(1)
-- Set to Constant, where motor rotational velocity = paramB
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Constant, 0, 0.25)
task.wait(2)
-- Set to Sin, where motor rotational velocity = paramA * math.sin(time * paramB)
-- Since we're using pi (~3.14), the frequency of rotation is 1 second (per definition of sine function)
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Sin, 0.25, math.pi)
task.wait(3)
end

RightSurface

Read Parallel

The RightSurface property determines the type of surface used for the +X direction of a part. When two parts' faces are placed next to each other, they may create a joint between them. If set to Motor, the BasePart.RightSurfaceInput determines how a motor joint should behave.

Most SurfaceTypes render a texture on the part face if the BasePart.Material is set to Plastic. Some SurfaceTypes including Hinge, Motor, and SteppingMotor will render a 3D adornment instead. If this property is selected in the Properties window, it will be highlighted in the game world similar to that of a SurfaceSelection.

Code Samples

This code sample shows what each SurfaceType looks like on a part. In addition, it creates a BillboardGui label on the part with a TextLabel that reflects the name of the current SurfaceType.

Show All SurfaceTypes

local demoPart = script.Parent
-- Create a billboard gui to display what the current surface type is
local billboard = Instance.new("BillboardGui")
billboard.AlwaysOnTop = true
billboard.Size = UDim2.new(0, 200, 0, 50)
billboard.Adornee = demoPart
local textLabel = Instance.new("TextLabel")
textLabel.Size = UDim2.new(0, 200, 0, 50)
textLabel.BackgroundTransparency = 1
textLabel.TextStrokeTransparency = 0
textLabel.TextColor3 = Color3.new(1, 1, 1) -- White
textLabel.Parent = billboard
billboard.Parent = demoPart
local function setAllSurfaces(part, surfaceType)
part.TopSurface = surfaceType
part.BottomSurface = surfaceType
part.LeftSurface = surfaceType
part.RightSurface = surfaceType
part.FrontSurface = surfaceType
part.BackSurface = surfaceType
end
while true do
-- Iterate through the different SurfaceTypes
for _, enum in pairs(Enum.SurfaceType:GetEnumItems()) do
textLabel.Text = enum.Name
setAllSurfaces(demoPart, enum)
task.wait(1)
end
end

RightSurfaceInput

Hidden
Deprecated
Read Parallel

The RightSurfaceInput property determines the kind of input provided to a

  • For Sin, the motor rotates at a velocity equal to ParamA * math.sin(workspace.DistributedGameTime * ParamB). See Workspace.DistributedGameTime.

Code Samples

Motor Control

-- Paste this into a Script inside a part with a Motor SurfaceType
local partMotor = script.Parent
-- Place a brick called "MovingPart" so it is touching the Motor surface
-- For this example, we use TopSurface, TopSurfaceInput, TopParamA and TopParamB
-- However, this will work for all faces (NormalId): Top, Bottom, Left, Right, Front and Back
-- A function to quickly set all surface properties at once
local function setFaceSurfaceInputParams(normalId, surfaceType, inputType, paramA, paramB)
local surfaceName = normalId.Name -- e.g. "Top", "Bottom", etc
-- Syntax Note: in Lua, part.Something is the same as part["Something"]
-- The difference is that the latter allows us to use a string ("Something"), while
-- the former requires use of an identifier (.Something). Below, we build of each the surface
-- properties below by concatenating the surface name with the property postfix.
-- Set "___Surface", eg "TopSurface"
partMotor[surfaceName .. "Surface"] = surfaceType
-- Set "___SurfaceInput", eg "TopSurfaceInput"
partMotor[surfaceName .. "SurfaceInput"] = inputType
-- Set "___ParamA", eg "TopParamA"
partMotor[surfaceName .. "ParamA"] = paramA
-- Set "___ParamB", eg "TopParamB"
partMotor[surfaceName .. "ParamB"] = paramB
end
local normalId = Enum.NormalId.Top
while true do
-- Set to NoInput, where the motor will not operate at all
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.NoInput, 0, 0)
task.wait(1)
-- Set to Constant, where motor rotational velocity = paramB
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Constant, 0, 0.25)
task.wait(2)
-- Set to Sin, where motor rotational velocity = paramA * math.sin(time * paramB)
-- Since we're using pi (~3.14), the frequency of rotation is 1 second (per definition of sine function)
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Sin, 0.25, math.pi)
task.wait(3)
end

RootPriority

Read Parallel

This property is an integer between -127 and 127 that takes precedence over all other rules for root part sort. When considering multiple parts that are not Anchored and which share the same Massless value, a part with a higher RootPriority will take priority over those with lower RootPriority.

You can use this property to control which part of an assembly is the root part and keep the root part stable if size changes.

See also Assemblies, an article documenting what root parts are and how to use them.

RotVelocity

Hidden
Deprecated
Read Parallel

The RotVelocity of a part describes how its BasePart.Orientation is presently changing. In other words, this property describes how the fast part is rotating. The part only rotates if it is not anchored.

The unit of this property is radians per second.

Using this in conjunction with AlignOrientation allows for aligned parts to have matching RotVelocity and Orientation values.

Code Samples

Rotating a Part with RotVelocity

local RunService = game:GetService("RunService")
local part = Instance.new("Part")
part.Name = "RotatingPart"
part.Position = Vector3.new(0, 1, 0)
part.Parent = workspace
local function renderStepped()
part.RotVelocity = Vector3.new(0, 10, 0)
end
RunService.RenderStepped:Connect(renderStepped)

Rotation

Not Replicated
Read Parallel

The rotation of the part in degrees for the three axes.

When setting this property any Welds or Motor6Ds connected to this part will have the matching C0 or C1 property updated and to allow the part to move relative to any other parts it is joined to.

WeldConstraints will also be temporarily disabled and re-enabled during the move.

Not Replicated
Read Parallel

A part's Size property determines its visual dimensions, while ExtentsSize represents the actual size used by the physics engine, such as in collision detection. The individual dimensions (length, width, height) can be as low as 0.001 and as high as 2048. Size dimensions below 0.05 will be visually represented as if the part's dimensions are 0.05.

The size of the part determines its mass which is given by BasePart:GetMass(). A part's Size is used by a variety of other objects:

Code Samples

This code sample constructs a pyramid by stacking parts that get progressively smaller. It also colors the parts so they blend between a start color and end color.

Pyramid Builder

local TOWER_BASE_SIZE = 30
local position = Vector3.new(50, 50, 50)
local hue = math.random()
local color0 = Color3.fromHSV(hue, 1, 1)
local color1 = Color3.fromHSV((hue + 0.35) % 1, 1, 1)
local model = Instance.new("Model")
model.Name = "Tower"
for i = TOWER_BASE_SIZE, 1, -2 do
local part = Instance.new("Part")
part.Size = Vector3.new(i, 2, i)
part.Position = position
part.Anchored = true
part.Parent = model
-- Tween from color0 and color1
local perc = i / TOWER_BASE_SIZE
part.Color = Color3.new(
color0.R * perc + color1.R * (1 - perc),
color0.G * perc + color1.G * (1 - perc),
color0.B * perc + color1.B * (1 - perc)
)
position = position + Vector3.new(0, part.Size.Y, 0)
end
model.Parent = workspace

SpecificGravity

Read Only
Not Replicated
Deprecated
Read Parallel

The ratio of the part's density to the density of water determined by the BasePart.Material. Effects the part's behavior when in a water terrain cell. Essentially, SpecificGravity refers to how many times more dense a part is than water.

MaterialSpecificGravity
Plastic0.7
Wood0.35
Slate2.7
Concrete2.4
CorrodedMetal7.85
DiamondMetal7.85
Foil7.6
Grass0.9
Ice0.91
Marble2.56
Granite2.7
Brick1.92
Pebble2.4
Sand1.6
Fabric0.7
SmoothPlastic0.7
Metal7.85
WoodPlanks0.35
Cobblestone2.7

TopParamA

Hidden
Deprecated
Read Parallel

The TopParamA property is relevant when a part's BasePart.TopSurface is set to Motor or SteppingMotor and BasePart.TopSurfaceInput is set to Sin. It determines the amplitude of the motor's rotational velocity, using the following formula:

MotorVelocity = ParamA * math.sin(workspace.DistributedGameTime * ParamB)

In no other cases is this property used.

Code Samples

Motor Control

-- Paste this into a Script inside a part with a Motor SurfaceType
local partMotor = script.Parent
-- Place a brick called "MovingPart" so it is touching the Motor surface
-- For this example, we use TopSurface, TopSurfaceInput, TopParamA and TopParamB
-- However, this will work for all faces (NormalId): Top, Bottom, Left, Right, Front and Back
-- A function to quickly set all surface properties at once
local function setFaceSurfaceInputParams(normalId, surfaceType, inputType, paramA, paramB)
local surfaceName = normalId.Name -- e.g. "Top", "Bottom", etc
-- Syntax Note: in Lua, part.Something is the same as part["Something"]
-- The difference is that the latter allows us to use a string ("Something"), while
-- the former requires use of an identifier (.Something). Below, we build of each the surface
-- properties below by concatenating the surface name with the property postfix.
-- Set "___Surface", eg "TopSurface"
partMotor[surfaceName .. "Surface"] = surfaceType
-- Set "___SurfaceInput", eg "TopSurfaceInput"
partMotor[surfaceName .. "SurfaceInput"] = inputType
-- Set "___ParamA", eg "TopParamA"
partMotor[surfaceName .. "ParamA"] = paramA
-- Set "___ParamB", eg "TopParamB"
partMotor[surfaceName .. "ParamB"] = paramB
end
local normalId = Enum.NormalId.Top
while true do
-- Set to NoInput, where the motor will not operate at all
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.NoInput, 0, 0)
task.wait(1)
-- Set to Constant, where motor rotational velocity = paramB
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Constant, 0, 0.25)
task.wait(2)
-- Set to Sin, where motor rotational velocity = paramA * math.sin(time * paramB)
-- Since we're using pi (~3.14), the frequency of rotation is 1 second (per definition of sine function)
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Sin, 0.25, math.pi)
task.wait(3)
end

TopParamB

Hidden
Deprecated
Read Parallel

The TopParamB property is relevant when a part's BasePart.TopSurface is set to Motor or SteppingMotor and BasePart.TopSurfaceInput is set to Constant or Sin. For Constant, it determines the constant rotational velocity of the motor. For Sin, it determines the frequency of the motor's rotational velocity, using the following formula:

MotorVelocity = ParamB * math.sin(workspace.DistributedGameTime * ParamB)

In no other cases is this property used.

Code Samples

Motor Control

-- Paste this into a Script inside a part with a Motor SurfaceType
local partMotor = script.Parent
-- Place a brick called "MovingPart" so it is touching the Motor surface
-- For this example, we use TopSurface, TopSurfaceInput, TopParamA and TopParamB
-- However, this will work for all faces (NormalId): Top, Bottom, Left, Right, Front and Back
-- A function to quickly set all surface properties at once
local function setFaceSurfaceInputParams(normalId, surfaceType, inputType, paramA, paramB)
local surfaceName = normalId.Name -- e.g. "Top", "Bottom", etc
-- Syntax Note: in Lua, part.Something is the same as part["Something"]
-- The difference is that the latter allows us to use a string ("Something"), while
-- the former requires use of an identifier (.Something). Below, we build of each the surface
-- properties below by concatenating the surface name with the property postfix.
-- Set "___Surface", eg "TopSurface"
partMotor[surfaceName .. "Surface"] = surfaceType
-- Set "___SurfaceInput", eg "TopSurfaceInput"
partMotor[surfaceName .. "SurfaceInput"] = inputType
-- Set "___ParamA", eg "TopParamA"
partMotor[surfaceName .. "ParamA"] = paramA
-- Set "___ParamB", eg "TopParamB"
partMotor[surfaceName .. "ParamB"] = paramB
end
local normalId = Enum.NormalId.Top
while true do
-- Set to NoInput, where the motor will not operate at all
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.NoInput, 0, 0)
task.wait(1)
-- Set to Constant, where motor rotational velocity = paramB
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Constant, 0, 0.25)
task.wait(2)
-- Set to Sin, where motor rotational velocity = paramA * math.sin(time * paramB)
-- Since we're using pi (~3.14), the frequency of rotation is 1 second (per definition of sine function)
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Sin, 0.25, math.pi)
task.wait(3)
end
Read Parallel

The TopSurface property determines the type of surface used for the +Y direction of a part. When two parts' faces are placed next to each other, they may create a joint between them. If set to Motor, the BasePart.TopSurfaceInput determines how a motor joint should behave.

Most SurfaceTypes render a texture on the part face if the BasePart.Material is set to Plastic. Some SurfaceTypes - Hinge, Motor and SteppingMotor - will render a 3D adornment instead. If this property is selected in the Properties window, it will be highlighted in the game world similar to that of a SurfaceSelection.

Code Samples

This code sample shows what each SurfaceType looks like on a part. In addition, it creates a BillboardGui label on the part with a TextLabel that reflects the name of the current SurfaceType.

Show All SurfaceTypes

local demoPart = script.Parent
-- Create a billboard gui to display what the current surface type is
local billboard = Instance.new("BillboardGui")
billboard.AlwaysOnTop = true
billboard.Size = UDim2.new(0, 200, 0, 50)
billboard.Adornee = demoPart
local textLabel = Instance.new("TextLabel")
textLabel.Size = UDim2.new(0, 200, 0, 50)
textLabel.BackgroundTransparency = 1
textLabel.TextStrokeTransparency = 0
textLabel.TextColor3 = Color3.new(1, 1, 1) -- White
textLabel.Parent = billboard
billboard.Parent = demoPart
local function setAllSurfaces(part, surfaceType)
part.TopSurface = surfaceType
part.BottomSurface = surfaceType
part.LeftSurface = surfaceType
part.RightSurface = surfaceType
part.FrontSurface = surfaceType
part.BackSurface = surfaceType
end
while true do
-- Iterate through the different SurfaceTypes
for _, enum in pairs(Enum.SurfaceType:GetEnumItems()) do
textLabel.Text = enum.Name
setAllSurfaces(demoPart, enum)
task.wait(1)
end
end

TopSurfaceInput

Hidden
Deprecated
Read Parallel

The TopSurfaceInput property determines the kind of input provided to a part's BasePart.TopSurface. This is only relevant for Motor or SteppingMotor SurfaceTypes. This property determines how BasePart.TopParamA and BasePart.TopParamB are used. For brevity, these properties will be referred to as ParamA and ParamB, respectively.

  • By default, this is set to NoInput. This stops the motor altogether,
  • For Constant, the motor rotates at a constant velocity equal to ParamB.
  • For Sin, the motor rotates at a velocity equal to ParamA * math.sin(workspace.DistributedGameTime * ParamB). See Workspace.DistributedGameTime.

Code Samples

Motor Control

-- Paste this into a Script inside a part with a Motor SurfaceType
local partMotor = script.Parent
-- Place a brick called "MovingPart" so it is touching the Motor surface
-- For this example, we use TopSurface, TopSurfaceInput, TopParamA and TopParamB
-- However, this will work for all faces (NormalId): Top, Bottom, Left, Right, Front and Back
-- A function to quickly set all surface properties at once
local function setFaceSurfaceInputParams(normalId, surfaceType, inputType, paramA, paramB)
local surfaceName = normalId.Name -- e.g. "Top", "Bottom", etc
-- Syntax Note: in Lua, part.Something is the same as part["Something"]
-- The difference is that the latter allows us to use a string ("Something"), while
-- the former requires use of an identifier (.Something). Below, we build of each the surface
-- properties below by concatenating the surface name with the property postfix.
-- Set "___Surface", eg "TopSurface"
partMotor[surfaceName .. "Surface"] = surfaceType
-- Set "___SurfaceInput", eg "TopSurfaceInput"
partMotor[surfaceName .. "SurfaceInput"] = inputType
-- Set "___ParamA", eg "TopParamA"
partMotor[surfaceName .. "ParamA"] = paramA
-- Set "___ParamB", eg "TopParamB"
partMotor[surfaceName .. "ParamB"] = paramB
end
local normalId = Enum.NormalId.Top
while true do
-- Set to NoInput, where the motor will not operate at all
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.NoInput, 0, 0)
task.wait(1)
-- Set to Constant, where motor rotational velocity = paramB
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Constant, 0, 0.25)
task.wait(2)
-- Set to Sin, where motor rotational velocity = paramA * math.sin(time * paramB)
-- Since we're using pi (~3.14), the frequency of rotation is 1 second (per definition of sine function)
setFaceSurfaceInputParams(normalId, Enum.SurfaceType.Motor, Enum.InputType.Sin, 0.25, math.pi)
task.wait(3)
end

Transparency

Read Parallel

The Transparency property controls the visibility of a part on a scale of 0 to 1, where 0 is completely visible (opaque), and a value of 1 is completely invisible (not rendered at all).

BasePart.Reflectance can reduce the overall transparency of a brick if set to a value close to 1.

While fully transparent parts are not rendered at all, partially transparent objects have some significant rendering costs. Having many translucent parts may slow down the game's performance.

When transparent parts overlap, render order can act unpredictable - try to keep semi-transparent parts from overlapping to avoid this.

The BasePart.LocalTransparencyModifier is a multiplier to Transparency that is only visible to the local client.

Code Samples

This code sample shows how a part can fade away when touched by a Humanoid then reappear a moment after to create a passable door.

Fade Door

-- Paste into a Script inside a tall part
local part = script.Parent
local OPEN_TIME = 1
-- Can the door be opened at the moment?
local debounce = false
local function open()
part.CanCollide = false
part.Transparency = 0.7
part.BrickColor = BrickColor.new("Black")
end
local function close()
part.CanCollide = true
part.Transparency = 0
part.BrickColor = BrickColor.new("Bright blue")
end
local function onTouch(otherPart)
-- If the door was already open, do nothing
if debounce then
print("D")
return
end
-- Check if touched by a Humanoid
local human = otherPart.Parent:FindFirstChildOfClass("Humanoid")
if not human then
print("not human")
return
end
-- Perform the door opening sequence
debounce = true
open()
task.wait(OPEN_TIME)
close()
debounce = false
end
part.Touched:Connect(onTouch)
close()

This code sample gives the local client X-ray vision using LocalTransparencyModifier. It allows the player to see through all parts in the Workspace, which are found using recursion.

X-Ray Vision

local function makeXRayPart(part)
-- LocalTransparencyModifier will make parts see-through but only for the local
-- client, and it won't replicate to the server
part.LocalTransparencyModifier = 0.5
end
-- This function uses recursion to search for parts in the game
local function recurseForParts(object)
if object:IsA("BasePart") then
makeXRayPart(object)
end
-- Stop if this object has a Humanoid - we don't want to see-through players!
if object:FindFirstChildOfClass("Humanoid") then
return
end
-- Check the object's children for more parts
for _, child in pairs(object:GetChildren()) do
recurseForParts(child)
end
end
recurseForParts(workspace)

Velocity

Hidden
Deprecated
Read Parallel

The Velocity of a part describes how its BasePart.Position is presently changing. The unit of this property is studs per second. For reference, the default Roblox character moves at 16 studs per second via Humanoid.WalkSpeed. The acceleration due to gravity is found in Workspace.Gravity (by default, -196.2 studs per second per second).

Setting the Velocity of a part that is BasePart.Anchored will cause it to act like a conveyor belt. Any object that touches the part will begin to move in accordance with the Velocity.

Some BodyMover objects will apply forces and thus change the Velocity of a part over time. The simplest of these is a BodyForce which can be used to counteract the acceleration due to gravity on a single part (set the +Y axis of the BodyForce.Force to the product of the mass (BasePart:GetMass()) and the gravity constant).

Code Samples

Projectile Firing

-- Put this Script in a Part, preferably bullet-shaped :)
local part = script.Parent
part.Shape = Enum.PartType.Ball
part.Size = Vector3.new(2, 2, 2)
part.BrickColor = BrickColor.new("Really black")
part.CanCollide = false
local MY_START_POINT = Vector3.new(0, 50, 0)
local MY_TARGET_POINT = Vector3.new(50, 100, 0)
local TRAVEL_TIME = 1
local ANTI_GRAVITY = 0.5
-- Anti-gravity effect: add a BodyForce to counter gravity
local bf = Instance.new("BodyForce")
bf.Force = Vector3.new(0, workspace.Gravity * part:GetMass() * ANTI_GRAVITY, 0)
bf.Parent = part
local a0 = Instance.new("Attachment")
a0.Position = Vector3.new(1, 0, 0)
a0.Parent = part
local a1 = Instance.new("Attachment")
a1.Position = Vector3.new(-1, 0, 0)
a1.Parent = part
local trail = Instance.new("Trail")
trail.Parent = part
trail.Attachment0 = a0
trail.Attachment1 = a1
trail.FaceCamera = true
trail.Transparency = NumberSequence.new({
NumberSequenceKeypoint.new(0, 0),
NumberSequenceKeypoint.new(1, 1),
})
trail.Lifetime = 0.35
local function fire(startPoint, targetPoint)
-- Calculate how far we have to travel
local distance = (targetPoint - startPoint).magnitude
local speed = distance / TRAVEL_TIME
part.CFrame = CFrame.new(startPoint, targetPoint)
-- Shoot the part
part.Velocity = part.CFrame.LookVector * speed
end
while true do
fire(MY_START_POINT, MY_TARGET_POINT)
task.wait(TRAVEL_TIME)
end

brickColor

Not Replicated
Deprecated
Read Parallel

Methods

AngularAccelerationToTorque

Parameters

angAcceleration: Vector3
angVelocity: Vector3
Default Value: "0, 0, 0"

Returns

ApplyAngularImpulse

void

Applies an instant angular force impulse to this part's assembly, causing the assembly to spin.

The resulting angular velocity from the impulse relies on the assembly's mass. So a higher impulse is required to move more massive assemblies. Impulses are useful for cases where you want a force applied instantly, such as an explosion or collision.

If the part is owned by the server, this function must be called from a server Script (not from a LocalScript or a Script with RunContext set to Enum.RunContext.Client). If the part is owned by a client through automatic ownership, this function can be called from either a client script or a server script; calling it from a client script for a server-owned part will have no effect.

Parameters

impulse: Vector3

An angular impulse vector to be applied to the assembly.


Returns

void

ApplyImpulse

void

This function applies an instant force impulse to this part's assembly.

The force is applied at the assembly's center of mass, so the resulting movement will only be linear.

The resulting velocity from the impulse relies on the assembly's mass. So a higher impulse is required to move more massive assemblies. Impulses are useful for cases where you want a force applied instantly, such as an explosion or collision.

If the part is owned by the server, this function must be called from a server Script (not from a LocalScript or a Script with RunContext set to Enum.RunContext.Client). If the part is owned by a client through automatic ownership, this function can be called from either a client script or a server script; calling it from a client script for a server-owned part will have no effect.

Parameters

impulse: Vector3

A linear impulse vector to be applied to the assembly.


Returns

void

ApplyImpulseAtPosition

void

This function applies an instant force impulse to this part's assembly, at the specified position in world space.

If the position is not at the assembly's center of mass, the impulse will cause a positional and rotational movement.

The resulting velocity from the impulse relies on the assembly's mass. So a higher impulse is required to move more massive assemblies. Impulses are useful for cases where developers want a force applied instantly, such as an explosion or collision.

If the part is owned by the server, this function must be called from a server Script (not from a LocalScript or a Script with RunContext set to Enum.RunContext.Client). If the part is owned by a client through automatic ownership, this function can be called from either a client script or a server script; calling it from a client script for a server-owned part will have no effect.

Parameters

impulse: Vector3

An impulse vector to be applied to the assembly.

position: Vector3

The position, in world space, to apply the impulse.


Returns

void

BreakJoints

void
Deprecated

Breaks any surface connection with any adjacent part, including Weld and other JointInstance.


Returns

void

CanCollideWith

Write Parallel

Returns whether the parts can collide with each other or not. This function takes into account the collision groups of the two parts. This function will error if the specified part is not a BasePart.

Parameters

part: BasePart

The specified part being checked for collidability.


Returns

Whether the parts can collide with each other.

CanSetNetworkOwnership

The CanSetNetworkOwnership function checks whether you can set a part's network ownership.

The function's return value verifies whether or not you can call BasePart:SetNetworkOwner() or BasePart:SetNetworkOwnershipAuto() without encountering an error. It returns true if you can modify/read the network ownership, or returns false and the reason you can't, as a string.


Returns

Whether you can modify or read the network ownership and the reason.

Code Samples

This example checks whether or not the network ownership of the first BasePart named Part in the Workspace can be set.

Check if a Part's Network Ownership Can Be Set

local part = workspace:FindFirstChild("Part")
if part and part:IsA("BasePart") then
local canSet, errorReason = part:CanSetNetworkOwnership()
if canSet then
print(part:GetFullName() .. "'s Network Ownership can be changed!")
else
warn("Cannot change the Network Ownership of " .. part:GetFullName() .. " because: " .. errorReason)
end
end

GetClosestPointOnSurface

Parameters

position: Vector3

Returns

GetConnectedParts

Instances
Write Parallel

Returns a table of parts connected to the object by any kind of rigid joint.

If recursive is true this function will return all of the parts in the assembly rigidly connected to the BasePart.

Rigid Joints

When a joint connects two parts together (Part0 → Part1), a joint is rigid if the physics of Part1 are completely locked down by Part0. This only applies to the following joint types:

Parameters

recursive: bool

A table of parts connected to the object by any kind of joint.

Default Value: false

Returns

Instances

GetJoints

Instances
Write Parallel

Return all Joints or Constraints that is connected to this Part.


Returns

Instances

An array of all Joints or Constraints connected to the Part.

GetMass

Write Parallel

GetMass returns the value of the read-only Mass property.

This function predates the Mass property. It remains supported for backward-compatibility; you should use the Mass property directly.


Returns

The part's mass.

Code Samples

This example creates a new part, myPart, in the game's Workspace, with dimensions 4x6x4 studs. The part is also anchored.

Then, myMass is set to equal the mass of the new part. The mass of the part is printed at the end of the print statement:

My part's mass is ...

Finding a Part's Mass

local myPart = Instance.new("Part")
myPart.Size = Vector3.new(4, 6, 4)
myPart.Anchored = true
myPart.Parent = workspace
local myMass = myPart:GetMass()
print("My part's mass is " .. myMass)

GetNetworkOwner

Write Parallel

Returns the current player who is the network owner of this part, or nil in case of the server.


Returns

The current player who is the network owner of this part, or nil in case of the server.

GetNetworkOwnershipAuto

Write Parallel

Returns true if the game engine automatically decides the network owner for this part.


Returns

Whether the game engine automatically decides the network owner for this part.

GetNoCollisionConstraints

Instances

Returns

Instances

GetRenderCFrame

Deprecated

This function used to be relevant when Roblox's lag-compensating interpolation of parts online was internal. The interpolation is now applied to the CFrame directly.


Returns

GetRootPart

Write Parallel

Returns the base part of an assembly. When moving an assembly of parts using a CFrame. it is important to move this base part (this will move all other parts connected to it accordingly). More information is available in the Assemblies article.

This function predates the AssemblyRootPart property. It remains supported for backwards compatibility, but you should use AssemblyRootPart directly.


Returns

The base part of an assembly (a collection of parts connected together).

GetTouchingParts

Instances

Returns a table of all parts that are physically interacting with this part. If the part itself has CanCollide set to false, then this function returns an empty table unless the part has a TouchInterest object parented to it (meaning something is connected to its Touched event). Parts that are adjacent but not intersecting are not considered touching. This function predates the WorldRoot:GetPartsInPart() function, which provides more flexibility and avoids the special TouchInterest rules described above. Use WorldRoot:GetPartsInPart() instead.


Returns

Instances

A table of all parts that intersect and can collide with this part.

GetVelocityAtPosition

Write Parallel

Returns the linear velocity of the part's assembly at the given position relative to this part. It can be used to identify the linear velocity of parts in an assembly other than the root part. If the assembly has no angular velocity, than the linear velocity will always be the same for every position.

Parameters

position: Vector3

Returns

IsGrounded

Write Parallel

Returns true if the object is connected to a part that will hold it in place (eg an Anchored part), otherwise returns false. In an assembly that has an Anchored part, every other part is grounded.


Returns

Whether the object is connected to a part that will hold it in place.

MakeJoints

void
Deprecated

Creates a joint on any side of the Part that has a Enum.SurfaceType that can make a joint it will create a joint with any adjacent parts.

Joints will be created between the sides and any planar touching surfaces, depending on the sides' surfaces.

  • Smooth surfaces will not create joints
  • Glue surfaces will create a Glue joint
  • Weld will create a Weld joint with any surface except for Unjoinable
  • Studs, Inlet, or Universal will each create a Snap joint with either of other the other two surfaces (e.g. Studs with Inlet and Universal)
  • Hinge and Motor surfaces create Rotate and RotateV joint instances

Unlike Model:MakeJoints(), this function requires an array of parts as a parameter. This array is given as follows:


part:MakeJoints({part1, part2, part3})

Joints are broken if enough force is applied to them due to an Explosion, unless a ForceField object is parented to the BasePart or ancestor Model. For this reason, they are often used to make simple destructible buildings and other models.


Returns

void

Resize

Changes the size of an object just like using the Studio resize tool.

Parameters

normalId: Enum.NormalId

The side to resize.

deltaAmount: number

How much to grow/shrink on the specified side.


Returns

Whether the part is resized.

SetNetworkOwner

void

Sets the given player as network owner for this and all connected parts. When playerInstance is nil, the server will be the owner instead of a player.

Parameters

playerInstance: Player

The player being given network ownership of the part.

Default Value: "nil"

Returns

void

SetNetworkOwnershipAuto

void

Lets the game engine dynamically decide who will handle the part's physics (one of the clients or the server).


Returns

void

TorqueToAngularAcceleration

Parameters

torque: Vector3
angVelocity: Vector3
Default Value: "0, 0, 0"

Returns

breakJoints

void
Deprecated

Returns

void

getMass

Deprecated

Returns

makeJoints

void
Deprecated

Returns

void

resize

Deprecated

Parameters

normalId: Enum.NormalId
deltaAmount: number

Returns

IntersectAsync

Yields

Creates a new IntersectOperation from the intersecting geometry of the part and the other parts in the given array. Only Parts are supported, not Terrain or MeshParts. Similar to Clone(), the returned object has no set Parent.

The following properties from the calling part are applied to the resulting IntersectOperation:

In the following image comparison, IntersectAsync() is called on the purple block using a table containing the blue block. The resulting IntersectOperation resolves into a shape of the intersecting geometry of both parts.

Two block parts overlapping
Separate parts
Parts intersected into a new solid model
Resulting IntersectOperation

Notes

  • The original parts remain intact following a successful intersect operation. In most cases, you should Destroy() all of the original parts and parent the returned IntersectOperation to the same place as the calling BasePart.
  • By default, the face colors of the resulting intersection are borrowed from the Color property of the original parts. To change the entire intersection to a specific color, set its UsePartColor property to true.
  • If an intersect operation would result in a part with more than 20,000 triangles, it will be simplified to 20,000 triangles.

Parameters

parts: Instances

The objects taking part in the intersection.

collisionfidelity: Enum.CollisionFidelity

The Enum.CollisionFidelity value for the resulting IntersectOperation.

Default Value: "Default"
renderFidelity: Enum.RenderFidelity

The Enum.RenderFidelity value of the resulting PartOperation.

Default Value: "Automatic"

Returns

Resulting IntersectOperation with default name Intersect.

SubtractAsync

Yields

Creates a new UnionOperation from the part, minus the geometry occupied by the parts in the given array. Only Parts are supported, not Terrain or MeshParts. Similar to Clone(), the returned object has no set Parent.

Note that the resulting union cannot be empty due to subtractions. If the operation would result in completely empty geometry, it will fail.

In the following image comparison, SubtractAsync() is called on the blue cylinder using a table containing the purple block. The resulting UnionOperation resolves into a shape that omits the block's geometry from that of the cylinder.

Longer block overlapping a cylinder
Separate parts
Block part subtracted from cylinder
Resulting UnionOperation

Parameters

parts: Instances

The objects taking part in the subtraction.

collisionfidelity: Enum.CollisionFidelity

The Enum.CollisionFidelity value for the resulting UnionOperation.

Default Value: "Default"
renderFidelity: Enum.RenderFidelity

The Enum.RenderFidelity value of the resulting PartOperation.

Default Value: "Automatic"

Returns

Resulting UnionOperation with default name Union.

Code Samples

This example demonstrates how to subtract part(s) from another BasePart to form a negated UnionOperation.

BasePart:SubtractAsync()

local Workspace = game:GetService("Workspace")
local mainPart = script.Parent.PartA
local otherParts = { script.Parent.PartB, script.Parent.PartC }
-- Perform subtract operation
local success, newSubtract = pcall(function()
return mainPart:SubtractAsync(otherParts)
end)
-- If operation succeeds, position it at the same location and parent it to the workspace
if success and newSubtract then
newSubtract.Position = mainPart.Position
newSubtract.Parent = Workspace
end
-- Destroy original parts which remain intact after operation
mainPart:Destroy()
for _, part in otherParts do
part:Destroy()
end

UnionAsync

Yields

Creates a new UnionOperation from the part, plus the geometry occupied by the parts in the given array. Only Parts are supported, not Terrain or MeshParts. Similar to Clone(), the returned object has no set Parent.

The following properties from the calling part are applied to the resulting UnionOperation:

In the following image comparison, UnionAsync() is called on the blue block using a table containing the purple cylinder. The resulting UnionOperation resolves into a shape of the combined geometry of both parts.

Block and cylinder parts overlapping
Separate parts
Parts joined together into a single solid union
Resulting UnionOperation

Notes

  • The original parts remain intact following a successful union operation. In most cases, you should Destroy() all of the original parts and parent the returned UnionOperation to the same place as the calling BasePart.
  • By default, the resulting union respects the Color property of each of its parts. To change the entire union to a specific color, set its UsePartColor property to true.
  • If a union operation would result in a part with more than 20,000 triangles, it will be simplified to 20,000 triangles.

Parameters

parts: Instances

The objects taking part in the union with the calling part.

collisionfidelity: Enum.CollisionFidelity

The Enum.CollisionFidelity value for the resulting UnionOperation.

Default Value: "Default"
renderFidelity: Enum.RenderFidelity

The Enum.RenderFidelity value of the resulting PartOperation.

Default Value: "Automatic"

Returns

Resulting UnionOperation with default name Union.

Code Samples

This example demonstrates how to combine the geometry of one BasePart with the geometry of other part(s) to form a UnionOperation.

BasePart:UnionAsync()

local Workspace = game:GetService("Workspace")
local mainPart = script.Parent.PartA
local otherParts = { script.Parent.PartB, script.Parent.PartC }
-- Perform union operation
local success, newUnion = pcall(function()
return mainPart:UnionAsync(otherParts)
end)
-- If operation succeeds, position it at the same location and parent it to the workspace
if success and newUnion then
newUnion.Position = mainPart.Position
newUnion.Parent = Workspace
end
-- Destroy original parts which remain intact after operation
mainPart:Destroy()
for _, part in otherParts do
part:Destroy()
end

Events

LocalSimulationTouched

Deprecated

Fired when another part comes in contact with another object. This event only sends data to the client notifying it that two parts have collided, whereas BasePart.Touched sends data to the server.

Parameters

part: BasePart

Code Samples

BasePart.LocalSimulationTouched

workspace.Part.LocalSimulationTouched:Connect(function(part)
print(part.Name)
end)

OutfitChanged

Deprecated

Fired if the part's appearance is affected by the Shirt class.


StoppedTouching

Deprecated

Parameters

otherPart: BasePart

TouchEnded

Fires when a part stops touching another part under similar conditions to those of BasePart.Touched.

This event works in conjunction with Workspace.TouchesUseCollisionGroups to specify whether collision groups are acknowledged for detection.

Parameters

otherPart: BasePart

Code Samples

This code sample creates a BillboardGui on a part that displays the number of parts presently touching it.

Touching Parts Count

local part = script.Parent
local billboardGui = Instance.new("BillboardGui")
billboardGui.Size = UDim2.new(0, 200, 0, 50)
billboardGui.Adornee = part
billboardGui.AlwaysOnTop = true
billboardGui.Parent = part
local tl = Instance.new("TextLabel")
tl.Size = UDim2.new(1, 0, 1, 0)
tl.BackgroundTransparency = 1
tl.Parent = billboardGui
local numTouchingParts = 0
local function onTouch(otherPart)
print("Touch started: " .. otherPart.Name)
numTouchingParts = numTouchingParts + 1
tl.Text = numTouchingParts
end
local function onTouchEnded(otherPart)
print("Touch ended: " .. otherPart.Name)
numTouchingParts = numTouchingParts - 1
tl.Text = numTouchingParts
end
part.Touched:Connect(onTouch)
part.TouchEnded:Connect(onTouchEnded)

Touched

The Touched event fires when a part comes in contact with another part. For instance, if PartA bumps into PartB, then PartA.Touched fires with PartB, and PartB.Touched fires with PartA.

This event only fires as a result of physical movement, so it will not fire if the CFrame property was changed such that the part overlaps another part. This also means that at least one of the parts involved must not be Anchored at the time of the collision.

This event works in conjunction with Workspace.TouchesUseCollisionGroups to specify whether collision groups are acknowledged for detection.

Parameters

otherPart: BasePart

The other part that came in contact with the given part.


Code Samples

This code sample creates a BillboardGui on a part that displays the number of parts presently touching it.

Touching Parts Count

local part = script.Parent
local billboardGui = Instance.new("BillboardGui")
billboardGui.Size = UDim2.new(0, 200, 0, 50)
billboardGui.Adornee = part
billboardGui.AlwaysOnTop = true
billboardGui.Parent = part
local tl = Instance.new("TextLabel")
tl.Size = UDim2.new(1, 0, 1, 0)
tl.BackgroundTransparency = 1
tl.Parent = billboardGui
local numTouchingParts = 0
local function onTouch(otherPart)
print("Touch started: " .. otherPart.Name)
numTouchingParts = numTouchingParts + 1
tl.Text = numTouchingParts
end
local function onTouchEnded(otherPart)
print("Touch ended: " .. otherPart.Name)
numTouchingParts = numTouchingParts - 1
tl.Text = numTouchingParts
end
part.Touched:Connect(onTouch)
part.TouchEnded:Connect(onTouchEnded)

This code sample demonstrates how to connect the BasePart.Touched event of multiple parts in a Model to one function.

Model Touched

local model = script.Parent
local function onTouched(otherPart)
-- Ignore instances of the model coming in contact with itself
if otherPart:IsDescendantOf(model) then return end
print(model.Name .. " collided with " .. otherPart.Name)
end
for _, child in pairs(model:GetChildren()) do
if child:IsA("BasePart") then
child.Touched:Connect(onTouched)
end
end