Workspace

Show Deprecated
Not Creatable
Service

The core job of Workspace is to hold objects that exist in the 3D world, effectively BaseParts and Attachments. While such objects are descendant of Workspace, they will be active. For BaseParts, this means they will be rendered, and physically interact with other parts and the world. For Attachments, this means that objects adorned to them, such as ParticleEmitters, Beams, and BillboardGuis, will render.

Understanding this behavior is important, as it means objects can be removed from Workspace when they are not needed. For example, map Models can be removed when a different map is being played on. Objects that are not immediately needed in the 3D world are generally stored in ReplicatedStorage or ServerStorage.

In its role as the holder of active 3D objects, Workspace includes a number of useful functions related to parts, their positions, and joints between them.

Accessing the Workspace

Workspace can be accessed several ways, all of which are valid.

  • workspace
  • game:GetService("Workspace")
  • game.Workspace
Notes

Summary

Properties

Properties inherited from ModelProperties inherited from PVInstance

Methods

Methods inherited from WorldRootMethods inherited from ModelMethods inherited from PVInstance

Events

Properties

AirDensity

Read Parallel

The ground level (Y of 0) air density in RMU/stud³ units (see Roblox Units), used to calculate the aerodynamic force if Workspace.FluidForces is Experimental. The default corresponds to realistic sea level air density at standard temperature and pressure. Air density decays as the Y altitude increases, reaching 5% of its ground level value at 100,000 studs. Below Y of 0, the air density is fixed at the input value.

AllowThirdPartySales

Not Replicated
Read Parallel

This Workspace property determines whether assets created by other uses can be sold in the game.

What are third party sales?

When this value is false, as it is by default, only assets created by the place creator (be it a player or a group) and Roblox can be sold using MarketplaceService.

In most cases, games do not need to sell third party assets. However, some games such as trade hangouts require this feature and therefore it exists as an opt-in option.

What third party products can I sell?

Note, developer products can only be sold in the game they are associated with, regardless of what AllowThirdPartySales is set to. This property affects Game Passes and clothing.

AvatarUnificationMode

Not Scriptable
Read Parallel

ClientAnimatorThrottling

Read Parallel

Specifies the Enum.ClientAnimatorThrottlingMode to use for the local client.

When enabled, animations on remotely-simulated Model instances will begin to throttle. The throttler calculates throttling intensity using:

  • Visibility of a Model in relation to the Camera
  • In-game FPS
  • Number of active animations

CurrentCamera

Not Replicated
Read Parallel

The Camera object being used by the local player.

How to use CurrentCamera

When looking for a client's Camera object, use this property rather than looking for a child of Workspace named "Camera".

When you set this property, all other Camera objects in the Workspace are destroyed, including the previous CurrentCamera. If you set this property to nil or to a camera that is not a descendant of the Workspace (or the CurrentCamera is otherwise destroyed), a new Camera will be created and assigned. Avoid these scenarios, as destroying the camera can have unintended consequences.

For more information, see Scripting the Camera.

DistributedGameTime

Not Replicated
Read Parallel

The amount of time, in seconds, that the game has been running.

Despite the title, this value is currently not 'Distributed' across the client and the server. Instead, on the server it represents how long the server has been running. On the client, it represents how long the client has been connected to the server.

Developers should not rely on the above behavior, and it is possible this property will be synchronized across clients and the server in the future.

Those looking for the time since the program started running should use the 'time' function instead. See below for a comparison between DistributedGameTime and its alternatives.


local Workspace = game:GetService("Workspace")
print(Workspace.DistributedGameTime) -- Time the game started running
print(os.time()) -- Time since epoch (1 January 1970, 00:00:00) UTC
print(tick()) -- Time since epoch (1 January 1970, 00:00:00) system time
print(time()) -- Time the game started running
print(elapsedTime()) -- Time since Roblox started running

FallHeightEnabled

Plugin Security
Read Parallel

FallenPartsDestroyHeight

Plugin Security
Read Parallel

This property determines the height at which the Roblox Engine automatically removes falling BaseParts and their ancestor Models from Workspace by parenting them to nil. This is to prevent parts that have fallen off the map from continuing to fall forever.

If a part removed due to this behavior is the last part in a Model, that model will also be removed. This applies to all model ancestors of the part.

This property is clamped between -50,000 and 50,000 because BaseParts do not simulate or render properly at a great distance from the origin due to floating point inaccuracies.

This property can be read by scripts, but can only be set by plugins, the command bar, or the properties window in Studio.

FilteringEnabled

Hidden
Not Replicated
Deprecated
Plugin Security
Read Parallel

This property is discontinued and no longer takes effect.

FluidForces

Not Scriptable
Read Parallel

With this property enabled, the physics engine computes aerodynamic forces on BaseParts whose EnableFluidForces property is true. The default, Default, disables aerodynamic forces. Note that this property cannot be set through scripting and instead must be toggled in Studio.

GlobalWind

Read Parallel

This property specifies the direction and strength that wind blows through the experience, affecting terrain grass, dynamic clouds, and particles. See the Global Wind article for details.

Gravity

Read Parallel

Determines the acceleration due to gravity applied to falling BaseParts. This value is measured in studs per second squared and by default is set to 196.2 studs/second2. By changing this value, developers can simulate the effects of lower or higher gravity in game.

Code Samples

This script creates a touch pad in the workspace that, when touched, will reduce the game's gravity. Activating the pad again will switch back to normal gravity.

Low Gravity Button

local MOON_GRAVITY_RATIO = 1.62 / 9.81
local DEFAULT_GRAVITY = 196.2
local MOON_GRAVITY = DEFAULT_GRAVITY * MOON_GRAVITY_RATIO
-- Create a touch pad
local pad = Instance.new("Part")
pad.Size = Vector3.new(5, 1, 5)
pad.Position = Vector3.new(0, 0.5, 0)
pad.Anchored = true
pad.BrickColor = BrickColor.new("Bright green")
pad.Parent = workspace
-- Listen for pad touch
local enabled = false
local debounce = false
local function onPadTouched(_hit)
if not debounce then
debounce = true
enabled = not enabled
workspace.Gravity = enabled and MOON_GRAVITY or DEFAULT_GRAVITY
pad.BrickColor = enabled and BrickColor.new("Bright red") or BrickColor.new("Bright green")
task.wait(1)
debounce = false
end
end
pad.Touched:Connect(onPadTouched)

IKControlConstraintSupport

Not Scriptable
Read Parallel

Enables support for constraints for IKControls. The Default value is the same as Enabled. If disabled, IKControls ignore physics constraints. See IKControl for additional details.

InsertPoint

Not Replicated
Read Parallel

InterpolationThrottling

Hidden
Not Replicated
Deprecated
Plugin Security
Read Parallel

MeshPartHeadsAndAccessories

Not Scriptable
Read Parallel

Sets whether character Heads and Accessories should be downloaded as MeshParts. The Default value is the same as Enabled. If this feature is enabled, built-in avatars will use MeshParts for the character's Head and Accessories.

ModelStreamingBehavior

Not Scriptable
Read Parallel

MoverConstraintRootBehavior

Not Scriptable
Read Parallel

Controls the logic used to select the assembly root part for mechanisms that use any of the following constraints:

When this property is set to Enum.MoverConstraintRootBehaviorMode.Enabled, these constraints will be ignored when selecting the assembly root part if the constraint does not transmit forces between two parts (some examples being AngularVelocity.ReactionTorqueEnabled set to false, AlignPosition.ReactionForceEnabled set to false, or AlignOrientation.Mode set to Enum.OrientationAlignmentMode.OneAttachment).

When this property is set to Enum.MoverConstraintRootBehaviorMode.Disabled, these constraints may be erroneously considered when selecting the assembly root part, leading to inconsistent network ownership and delays when adding these constraints to a mechanism.

PathfindingUseImprovedSearch

Not Scriptable
Read Parallel

PhysicsImprovedSleep

Not Scriptable
Read Parallel

PhysicsSteppingMethod

Not Scriptable
Read Parallel

Sets how the solver will advance the physics simulation forward in time. This option is not scriptable and must be set from the PhysicsSteppingMethod property of Workspace within Studio. See Adaptive Timestepping for details.

OptionDescription
AdaptiveThe engine attempts to assign optimal simulation rates for individual assemblies of either 240 Hz, 120 Hz, or 60 Hz. This setting is optimized for performance.
FixedAll simulated assemblies inside the workspace will advance forward at 240 Hz. This option is best for optimal stability and simulation accuracy.
DefaultThe current default is Fixed.

Note that when assemblies of different simulation rates become connected via Constraints or collisions, the combined mechanism will default to the highest simulation rate for stability.

PlayerCharacterDestroyBehavior

Not Scriptable
Read Parallel

PrimalPhysicsSolver

Not Scriptable
Read Parallel

RejectCharacterDeletions

Not Scriptable
Read Parallel

RenderingCacheOptimizations

Not Scriptable
Read Parallel

ReplicateInstanceDestroySetting

Not Scriptable
Read Parallel
Read Parallel

SandboxedInstanceMode

Not Scriptable
Read Parallel

SignalBehavior

Not Scriptable
Read Parallel

This property determines whether event handlers will be resumed immediately when the event fires, or deferred and then resumed at a later resumption point. Resumption points currently include:

For more information, see Deferred Events.

StreamOutBehavior

Not Scriptable
Read Parallel

The StreamOutBehavior controls where content will be unloaded from the ReplicationFocus based on device Memory Conditions, or based on Streaming Radius.

See also:

StreamingEnabled

Plugin Security
Read Parallel

The StreamingEnabled property determines whether game content streaming is enabled for the place. This property is not scriptable and therefore must be set on the Workspace object in Studio.

See also:

StreamingIntegrityMode

Not Scriptable
Read Parallel

If instance streaming is enabled, an experience may behave in unintended ways if a player's character moves into a region of the world that has not been streamed to their client. The streaming integrity feature offers a way to avoid those potentially problematic situations.

StreamingMinRadius

Not Scriptable
Read Parallel

The StreamingMinRadius property indicates the radius around the player's character or the current ReplicationFocus in which content will be streamed in at the highest priority. Defaults to 64 studs.

Care should be taken when increasing the default minimum radius since doing so will require more memory and more server bandwidth at the expense of other components.

See also:

StreamingTargetRadius

Not Scriptable
Read Parallel

The StreamingTargetRadius property controls the maximum distance away from the player's character or the current ReplicationFocus in which content will be streamed in. Defaults to 1024 studs.

Note that the engine is allowed to retain previously loaded content beyond the target radius, memory permitting.

See also:

Terrain

Read Only
Not Replicated
Read Parallel

This property is a reference to the Terrain object parented to the Workspace.

Terrain object within the Workspace hierarchy

See Environmental Terrain for more information.

TouchEventsUseCollisionGroups

Not Scriptable
Read Parallel

TouchesUseCollisionGroups

Not Scriptable
Read Parallel

This property determines whether parts in different groups set to not collide will ignore collisions and touch events. By default, the value of this property is set to false.

When this property is enabled, parts in different groups set to not collide will also ignore the CanTouch property, similar to how BasePart.CanCollide is ignored. For more information on the behavior of CanTouch, please visit its property page.

Methods

BreakJoints

()
Deprecated
Plugin Security

Goes through all BaseParts given, breaking any joints connected to these parts. This function will break any of the following types of joints:

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


local Workspace = game:GetService("Workspace")
Workspace:BreakJoints({part1, part2, part3})

Note, this function cannot be used by scripts and will only function in plugins.

Parameters

objects: Instances

An array of BaseParts for whom joints are to be broken.

Default Value: ""

Returns

()

GetNumAwakeParts

Write Parallel

Returns the number of BaseParts that are deemed physically active, due to being recently under the influence of physics.

This function provides a measure of how many BaseParts are being influenced by, or recently under the influence of, physical forces.


local Workspace = game:GetService("Workspace")
print(Workspace:GetNumAwakeParts())

Sleeping vs Awake Parts

In order to ensure good performance, Roblox sets BaseParts in which physics are not being applied to a 'sleeping' state. BaseParts with BasePart.Anchored set to true, for example, will always be sleeping as physics doesn't apply to them. When a force is applied to a non anchored BasePart, an 'awake' state will be applied. Whilst a BasePart is awake the Roblox physics engine will perform continuous calculations to ensure physical forces interact correctly with the part. Once the BasePart is no longer subject to physical forces, it will revert to a 'sleeping' state.


Returns

The number of awake parts.

GetPhysicsThrottling

Write Parallel

Returns an integer, between 0 and 100, representing the percentage of real-time that physics simulation is currently being throttled to.

This function can be used to determine whether, and to what degree, physics throttling is occurring.

What is physics throttling?

Physics throttling occurs when the physics engine detects it cannot keep up with the game in realtime. When physics is being throttled, it will update less frequently causing BaseParts to appear to move slower.

Without throttling, the physics simulation would fall further behind out of sync with the game. This can lead to lower frame rates and other undesirable behavior.

Objects associated with Humanoids are exempt from physics throttling.

See also Workspace:SetPhysicsThrottleEnabled().

Demonstrating physics throttling

Developers should always avoid creating places that overload the physics engine, as it leads to sub-par experience for players. Those wishing to simulate physics throttling for research purposes however, need only create a lot of Parts very quickly.


local Workspace = game:GetService("Workspace")
local i = 0
while true do
i += 1
if i % 5 == 0 then
task.wait()
end
local part = Instance.new("Part", Workspace)
end

Returns

The percentage of real-time that physics simulation is currently being throttled to.

GetRealPhysicsFPS

Write Parallel

Returns the number of frames per second that physics is currently being simulated at.

Using GetRealPhysicsFPS to combat exploiters

A common use of this function is to detect if exploiters are increasing their local physics frame rate to move faster. This is generally done by comparing the result returned by a client's GetRealPhysicsFPS to a maximum that will not be breached in normal circumstances (usually 65 or 70). If this limit is breached, developers can use the Player:Kick() function to remove that Player from the game. It is important to remember that, although this practice may be effective sometimes, client-side anti-exploiter measures are never 100% reliable.


Returns

Returns the number of frames per second that physics is currently being simulated at.

Code Samples

Speed exploiters commonly increase their local physics FPS in order to increase their character speed. This can be detected from a LocalScript by checking if the player's physics FPS is over the maximum:

Workspace:GetRealPhysicsFPS

local Players = game:GetService("Players")
local player = Players.LocalPlayer
while task.wait(1) do
if workspace:GetRealPhysicsFPS() > 65 then
player:Kick()
end
end

GetServerTimeNow

Write Parallel

GetServerTimeNow() returns the client's best approximation of the current time on the server. This is useful for creating synchronized experiences as every client will get about the same results regardless of their timezone or local clock.

This returns a Unix timestamp, similar to os.time(), that can be used with os.date() or with DateTime.fromUnixTimestamp().

The timestamp returned by this function is smoothed so that:

  • It is monotonic; its value will never decrease.
  • It moves at the same rate as the local clock to within 0.6%.

GetServerTimeNow() is expensive to call compared to DateTime.now(), and is less precise than os.clock(), so it should be used to make sure an event starts at the right real world time or to adjust things periodically to keep a series of events in sync.

This function relies on the server, so calling it from a client that isn't connected will throw an error. Also note that this function is not suitable for things like timed rewards as it is not secure compared to tracking such timers on the server.

See also:


Returns

The estimated Unix timestamp on the server.

JoinToOutsiders

()

This function creates joints between the specified Parts and any touching parts depending on the parts' surfaces and the specified joint creation mode.

This function creates joints between the specified Parts and any planar touching surfaces, depending on the parts' surfaces and the specified joint creation mode.

  • Glue, Studs, Inlets, Universal, Weld, and Smooth surfaces will all create Weld instances.
  • Spheres will not surface-weld to anything. The rounded sides of cylinders will not surface-weld, but the flat end sides will.
  • Hinge and Motor surfaces will still create Rotate and RotateP joint instances, regardless of part shape.

The first parameter is an array of BaseParts. Joints will only be created between the parts in the array and not in the array. Joints will not be created between the parts in the array.

The second parameter is a Enum.JointCreationMode that determines how joints will be created. Passing in either enum value, Enum.JointCreationMode.All or Enum.JointCreationMode.Surface, has the same behavior which equates to Join Always

This function is used by the Roblox Studio Move tool when the user finishes moving a selection. In conjunction with Plugin:GetJoinMode() and Workspace:UnjoinFromOutsiders() it can be used to retain join functionality when developing custom studio build tools. See the snippets below for an example.


local Workspace = game:GetService("Workspace")
-- Finished moving a selection; make joints
local function finishedMovingParts(parts)
local joinMode = Plugin:GetJoinMode()
Workspace:JoinToOutsiders(parts, joinMode)
end

local Workspace = game:GetService("Workspace")
-- Started moving a selection; break joints
local function startMovingParts(parts)
Workspace:UnjoinFromOutsiders(parts)
end

Parameters

objects: Instances

An array of BaseParts for whom joints are to be made.

Default Value: ""

The Enum.JointCreationMode to be used. Passing in Enum.JointCreationMode.All or Enum.JointCreationMode.Surface has the same behavior which equates to Join Always.

Default Value: ""

Returns

()

MakeJoints

()
Deprecated
Plugin Security

Deprecated

SurfaceType based joining is deprecated, do not use MakeJoints for new projects. WeldConstraints and HingeConstraints should be used instead.

Goes through all Parts given. If any part's side has a Enum.SurfaceType that can make a joint it will create a joint with any adjacent parts.

Joints will be created between the specified Parts and any planar touching surfaces, depending on the parts' 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:


local Workspace = game:GetService("Workspace")
Workspace: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.

Parameters

objects: Instances

An array of parts for whom joints are to be made.

Default Value: ""

Returns

()

PGSIsEnabled

Returns true if the game has the PGS Physics solver enabled.

As Workspace.PGSPhysicsSolverEnabled cannot be accessed by scripts, the PGSIsEnabled function allows developers to tell which physics solver the game is using.


Returns

True if the PGS solver is enabled.

UnjoinFromOutsiders

()

Breaks all joints between the specified BaseParts and other BaseParts.

This function requires an array of BaseParts. Note, joints will not be broken between these BaseParts (each other), only between these BaseParts and other BaseParts not in the array.

This function is used by the Roblox Studio Move tool when the user starts moving a selection. In conjunction with Plugin:GetJoinMode() and Workspace:JoinToOutsiders() it can be used to retain join functionality when developing custom Studio build tools. See the snippets below for an example.


local Workspace = game:GetService("Workspace")
-- Finished moving a selection; make joints
local function finishedMovingParts(parts)
local joinMode = Plugin:GetJoinMode()
Workspace:JoinToOutsiders(parts, joinMode)
end

local Workspace = game:GetService("Workspace")
-- Started moving a selection; break joints
local function startMovingParts(parts)
Workspace:UnjoinFromOutsiders(parts)
end

Parameters

objects: Instances

An array of BaseParts for whom joints are to be broken.

Default Value: ""

Returns

()

ZoomToExtents

()
Plugin Security

Positions and zooms the Workspace.CurrentCamera to show the extent of BaseParts currently in the Workspace.

This function was used in the, now removed, 'Zoom To Extents' button in Roblox Studio. It exhibits similar behavior to the 'Zoom To' (F shortcut) feature, however it shows the extents of the Workspace rather than the currently selected object.

This function cannot be used in scripts but will function in the command bar or plugins.


Returns

()
Properties inherited from Model

AddPersistentPlayer

()

Parameters

playerInstance: Player
Default Value: "nil"

Returns

()

BreakJoints

()
Deprecated

Breaks connections between BaseParts, including surface connections with any adjacent parts, WeldConstraints, and all Welds and other JointInstances.

When BreakJoints is used on a Player character Model, the character's Humanoid will die as it relies on the Neck joint.

Note that although joints produced by surface connections with adjacent Parts can technically be recreated using Model:MakeJoints(), this will only recreate joints produced by surfaces. Developers should not rely on this as following the joints being broken parts may no longer be in contact with each other.


Returns

()

Code Samples

In this sample the joints in every Player character Model added will be broken 3 seconds after spawning. Breaking these joints will cause the Humanoid to die.

Break Character Joints

local Players = game:GetService("Players")
local function onCharacterAdded(character)
task.wait(3)
character:BreakJoints()
end
local function onPlayerAdded(player)
player.CharacterAdded:Connect(onCharacterAdded)
end
Players.PlayerAdded:Connect(onPlayerAdded)

This code sample demonstrates manual creation of joints on two parts that are siblings of the script (PartA and PartB). It creates a joints on two touching parts with compatible surface types (Studs and Inlet).

Manual Joint Creation

local JointsService = game:GetService("JointsService")
local partA = script.Parent.PartA
local partB = script.Parent.PartB
local function join(part0, part1, jointClass, parent)
local newJoint = Instance.new(jointClass or "ManualWeld")
newJoint.Part0 = part0
newJoint.Part1 = part1
newJoint.C0 = CFrame.new()
newJoint.C1 = part1.CFrame:toObjectSpace(part0.CFrame)
newJoint.Parent = parent or part0
return newJoint
end
-- Create some joints and break them
join(partA, partB)
partA:BreakJoints()
-- Glue joints are wobbly
join(partA, partB, "Glue")
partA:BreakJoints()
-- Most of the time, joints ought to be put in JointsService
join(partA, partB, "Weld", JointsService)

GetBoundingBox

This function returns a description of a volume that contains all BasePart children within a Model. The volume's orientation is based on the orientation of the PrimaryPart, and matches the selection box rendered in Studio when the model is selected. Mirroring the behavior of Terrain:FillBlock(), it returns a CFrame representing the center of that bounding box and a Vector3 representing its size.

If there is no PrimaryPart for the model, the bounding box will be aligned to the world axes.


local Workspace = game:GetService("Workspace")
local model = Workspace.Model
local part = Workspace.Part
local orientation, size = model:GetBoundingBox()
-- Resize and position part equal to bounding box of model
part.Size = size
part.CFrame = orientation

Returns

A CFrame representing the orientation of the volume followed by a Vector3 representing the size of the volume.

GetExtentsSize

Returns the size of the smallest bounding box that contains all of the BaseParts in the Model. If Model.PrimaryPart exists then the bounding box will be aligned to that part. If a primary part has not been set then the function will chose a part in the model to align the bounding box to. As the selection of this part is not deterministic it is recommended to set a Model.PrimaryPart to get consistent results with this function.

Note this function only returns the size of the smallest bounding box, and the developer must employ their own method to obtain the position of the bounding box.


Returns

The Vector3 extents size of the Model.

Code Samples

The code sample below demonstrates how Model.GetExtentsSize can be used to get the size of the bounding box containing the parts.

Model GetExtentsSize

local model = Instance.new("Model")
model.Parent = workspace
local RNG = Random.new()
for _ = 1, 5 do
local part = Instance.new("Part")
part.Anchored = true
part.Size = Vector3.new(RNG:NextNumber(0.05, 5), RNG:NextNumber(0.05, 5), RNG:NextNumber(0.05, 5))
part.Parent = model
end
print(model:GetExtentsSize())

GetModelCFrame

Deprecated

This value historically returned the CFrame of a central position in the model.


Returns

GetModelSize

Deprecated

The GetModelSize function returns the Vector3 size of the Model.


Returns

Code Samples

This code would create a model, put some parts in it, position them randomly, and then print its size:

Model:GetModelSize

local model = Instance.new("Model")
model.Parent = workspace
local RNG = Random.new()
for _ = 1, 5 do
local part = Instance.new("Part")
part.Parent = model
part.Anchored = true
part.Size = Vector3.new(RNG:NextNumber(0.05, 5), RNG:NextNumber(0.05, 5), RNG:NextNumber(0.05, 5))
end
print(model:GetModelSize())

GetPersistentPlayers

Instances

When this method is called from a Script, it returns all the Player objects that this model is persistent for. When called from a LocalScript, this method only checks if this model is persistent for the LocalPlayer.


Returns

Instances

A table with all the Player objects that this model object is persistent for.

GetPrimaryPartCFrame

Deprecated

This function has been superseded by PVInstance:GetPivot() which acts as a replacement and does not change your code's behavior. Use PVInstance:GetPivot() for new work and migrate your existing Model:GetPrimaryPartCFrame() calls when convenient.

Returns the CFrame of the model's Model.PrimaryPart.

This function is equivalent to the following.


Model.PrimaryPart.CFrame

Note this function will throw an error if no primary part exists for the Model. If this behavior is not desired developers can do the following, which will be equal to nil if there is no primary part.


local cFrame = Model.PrimaryPart and Model.PrimaryPart.CFrame

Returns

Code Samples

The following code demonstrates how GetPrimaryPartCFrame and SetPrimaryPartCFrame can be used to rotate a model.

A simple model is created in the Workspace and a loop is started that will rotate the model 10 degrees around the Y axis every 0.2 seconds.

Rotating a Model

local START_POSITION = Vector3.new(0, 10, 0)
local model = Instance.new("Model")
local part1 = Instance.new("Part")
part1.Size = Vector3.new(4, 4, 4)
part1.CFrame = CFrame.new(START_POSITION)
part1.Anchored = true
part1.BrickColor = BrickColor.new("Bright yellow")
part1.Parent = model
local part2 = Instance.new("Part")
part2.Size = Vector3.new(2, 2, 2)
part2.CFrame = part1.CFrame * CFrame.new(0, 3, 0)
part2.Anchored = true
part2.BrickColor = BrickColor.new("Bright blue")
part2.Parent = model
-- set the primary part
model.PrimaryPart = part1
model.Parent = workspace
while true do
local primaryPartCFrame = model:GetPrimaryPartCFrame()
local newCFrame = primaryPartCFrame * CFrame.Angles(0, math.rad(1), 0)
model:SetPrimaryPartCFrame(newCFrame)
task.wait()
end

GetScale

Models contain a persistent canonical scale factor, which starts out at 1 for newly created models and changes as the model is scaled by calling Model/ScaleTo. This function returns the current canonical scale factor of the model.

The current scale factor does not directly impact the size of Instances under the model. It is used for content authoring and scripting purposes to remember how the model has been scaled relative to its original size.

Within a given session, the model will cache the precise original size information of the descendant Instances after the first Model/ScaleTo call. This means that calling ScaleTo(x) followed by ScaleTo(1) will get you back exactly the original configuration of the model with no floating point drift. Avoiding floating point drift is the motivation for having a ScaleTo function instead of a ScaleBy function.

The scale factor does impact engine behavior in one way: The scale factor of a model will be applied to joint offsets of animations played on an AnimationController under that model, so that animated rigs will correctly play back animations even when scaled.


Returns

The current canonical scale factor of the model.

Code Samples

This code sample demonstrates substituting in a replacement for all the copies of a tree model using PivotTo and ScaleTo. The pivot and scale of the models are used as a reference ensuring that the relative sizes and locations of the replacement models match those of the originals.

Substituting in a replacement model using PivotTo and ScaleTo

local CollectionService = game:GetService("CollectionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Find all the models with the tag we want to replace
local items = CollectionService:GetTagged("Tree")
local newModel = ReplicatedStorage.FancyTreeReplacementModel
for _, item in items do
-- Make the new item and scale / position it where the old one was
local newItem = newModel:Clone()
newItem:ScaleTo(item:GetScale())
newItem:PivotTo(item:GetPivot())
-- Add the same tag to the replacement
CollectionService:AddTag(newItem, "Tree")
-- Delete the old item and parent the new one
newItem.Parent = item.Parent
item:Destroy()
end

MakeJoints

()
Deprecated

SurfaceType based joining is deprecated. Don't use MakeJoints for new projects. Use WeldConstraints and HingeConstraints instead.

Goes through all Parts in the Model and creates joints between the specified Parts and any planar touching surfaces, depending on the parts' 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

This function doesn't work if the Part is not a descendant of Workspace. Therefore, you must first ensure the Model is parented to Workspace before using MakeJoints.


Returns

()

Code Samples

This code sample demonstrates how joints can be made using the Model:MakeJoints function.

A model is instanced, with two parts on top of each other. The top part is anchored and the bottom part is not. Normally, when parented to the Workspace the bottom part would fall to the Baseplate.

However, as TopSurface property of the bottom part is set to Enum.SurfaceType.Weld, this means that when Model:MakeJoints is ran a connection is made between them.

Therefore the bottom part does not drop until the joints in the model are broken. This is often done using Model:BreakJoints, but in this example the connection is broken using an explosion.

Model MakeJoints

local model = Instance.new("Model")
-- create one part on top of another
local topPart = Instance.new("Part")
topPart.Size = Vector3.new(5, 1, 5)
topPart.Position = Vector3.new(0, 10, 0)
topPart.BrickColor = BrickColor.new("Bright green")
topPart.Anchored = true -- anchor the top part
topPart.Parent = model
local bottomPart = Instance.new("Part")
bottomPart.Size = Vector3.new(8, 1, 8)
bottomPart.Position = Vector3.new(0, 9, 0)
bottomPart.BrickColor = BrickColor.new("Bright green")
bottomPart.Anchored = false -- leave bottom unanchored
bottomPart.Parent = model
topPart.BottomSurface = Enum.SurfaceType.Smooth
topPart.TopSurface = Enum.SurfaceType.Smooth
bottomPart.BottomSurface = Enum.SurfaceType.Smooth
bottomPart.TopSurface = Enum.SurfaceType.Weld -- 'Weld' to create a joint
model.Parent = workspace
model:MakeJoints()
task.wait(2)
-- unanchor the bottom part - part does not fall
print("Unanchored!")
bottomPart.BrickColor = BrickColor.new("Bright red")
bottomPart.Anchored = false
task.wait(2)
-- break the joints using an explosion - part falls
local explosion = Instance.new("Explosion")
explosion.Position = bottomPart.Position
explosion.Parent = workspace

This code sample demonstrates creation of joints on two parts that are siblings of the script (PartA and PartB). It uses MakeJoints on two touching parts with compatible surface types (Studs and Inlet).

Simple Joint Creation

local partA = script.Parent.PartA
local partB = script.Parent.PartB
-- Move PartB on top of PartA
partB.CFrame = partA.CFrame * CFrame.new(0, partB.Size.Y / 2 + partA.Size.Y / 2, 0)
-- Studs and Inlet will make joints
partA.TopSurface = Enum.SurfaceType.Studs
partB.BottomSurface = Enum.SurfaceType.Inlet
-- Automatically create a joint between PartA and PartB
partA:MakeJoints()

MoveTo

()

Moves the PrimaryPart to the given position. If a primary part has not been specified, the root part of the model will be used, but the root part is not deterministic and it is recommended that you always set a primary part when using MoveTo().

If there are any obstructions where the model is to be moved, such as Terrain or other BaseParts, the model will be moved vertically upward until there is nothing in the way. If this behavior is not desired, PVInstance:PivotTo() should be used instead.

Note that rotation is not preserved when moving a model with MoveTo(). It is recommended to use either TranslateBy() or PVInstance:PivotTo() if the current rotation of the model needs to be preserved.

Parameters

position: Vector3

The Vector3 the Model is moved to.

Default Value: ""

Returns

()

Code Samples

This sample demonstrates how Model:MoveTo avoids collisions.

A simple two part Model is created, and its PrimaryPart is set. An large obstruction part is placed next to it.

After 5 seconds Model:MoveTo is used to direct the model to move inside the obstruction part. However, as MoveTo will not move a model inside of an obstruction the Model is moved up on the Y axis and placed above the obstruction.

Model MoveTo

local START_POSITION = Vector3.new(-20, 10, 0)
local END_POSITION = Vector3.new(0, 10, 0)
local model = Instance.new("Model")
model.Parent = workspace
local part1 = Instance.new("Part")
part1.Size = Vector3.new(4, 4, 4)
part1.Position = START_POSITION
part1.Anchored = true
part1.BrickColor = BrickColor.new("Bright yellow")
part1.Parent = model
local part2 = Instance.new("Part")
part2.Size = Vector3.new(2, 2, 2)
part2.Position = START_POSITION + Vector3.new(0, 3, 0)
part2.Anchored = true
part2.BrickColor = BrickColor.new("Bright blue")
part2.Parent = model
model.PrimaryPart = part1
model.Parent = workspace
local obstruction = Instance.new("Part")
obstruction.Name = "Obstruction"
obstruction.Size = Vector3.new(10, 10, 10)
obstruction.Position = Vector3.new(0, 10, 0)
obstruction.Anchored = true
obstruction.BrickColor = BrickColor.new("Bright green")
obstruction.Parent = workspace
task.wait(3)
model:MoveTo(END_POSITION)

RemovePersistentPlayer

()

Parameters

playerInstance: Player
Default Value: "nil"

Returns

()

ResetOrientationToIdentity

()
Deprecated

Resets the rotation of the model's parts to the previously set identity rotation, which is done through the Model:SetIdentityOrientation() method.


Returns

()

ScaleTo

()

Models contain a persistent canonical scale factor, which starts out at 1 for newly created models. This function scales the model, around the pivot location, relative to how it would look at a scale factor of 1. To accomplish this it does two things:

  • Sets the current scale factor of the model to the specified value
  • Resizes and repositions all descendant Instances accordingly

The scaling of locations is done around the pivot location.

All "geometric" properties of descendant Instances will be scaled. That obviously includes the sizes of parts, but here are some other examples of properties which are scaled:

  • The length of joints like WeldConstraints, and Class.Rope|Ropes
  • Physical velocities and forces like Hinge.MaxServoTorque
  • Visual properties like sizes of particle emitters
  • Other length properties like Sound.RollOffMinDistance

Parameters

newScaleFactor: number
Default Value: ""

Returns

()

SetIdentityOrientation

()
Deprecated

Sets the identity rotation of the given model, allowing you to reset the rotation of the entire model later, through the use of the ResetOrientationToIdentity method.


Returns

()

SetPrimaryPartCFrame

()
Deprecated

This function has been superseded by PVInstance:PivotTo() which acts as a more performant replacement and does not change your code's behavior. Use PVInstance:PivotTo() for new work and migrate your existing Model:SetPrimaryPartCFrame() calls when convenient.

Sets the BasePart.CFrame of the model's Model.PrimaryPart. All other parts in the model will also be moved and will maintain their orientation and offset respective to the Model.PrimaryPart.

Note, this function will throw an error if no Model.PrimaryPart exists for the model. This can cause issues if, for example, the primary part was never set or has been destroyed.

Parameters

cframe: CFrame

The CFrame to be set.

Default Value: ""

Returns

()

TranslateBy

()

Shifts a Model by the given Vector3 offset, preserving the model's orientation. If another BasePart or Terrain already exists at the new position then the Model will overlap said object.

The translation is applied in world space rather than object space, meaning even if the model's parts are orientated differently it will still move along the standard axis.

Parameters

delta: Vector3

The Vector3 to translate the Model by.

Default Value: ""

Returns

()

Code Samples

This sample demonstrates how Model:TranslateBy ignores collisions and respects the orientation of the model.

A simple two part Model is created, rotated 45 degrees on the Y axis, and its PrimaryPart is set. An large obstruction part is placed next to it.

After 5 seconds Model:TranslateBy is used to direct the model to move inside the obstruction part. The model will move inside of the obstruction and maintain it's current orientation.

Model TranslateBy

local START_POSITION = Vector3.new(-20, 10, 0)
local END_POSITION = Vector3.new(0, 10, 0)
local model = Instance.new("Model")
local part1 = Instance.new("Part")
part1.Size = Vector3.new(4, 4, 4)
part1.CFrame = CFrame.new(START_POSITION) * CFrame.Angles(0, math.rad(45), 0)
part1.Anchored = true
part1.BrickColor = BrickColor.new("Bright yellow")
part1.Parent = model
local part2 = Instance.new("Part")
part2.Size = Vector3.new(2, 2, 2)
part2.CFrame = part1.CFrame * CFrame.new(0, 3, 0)
part2.Anchored = true
part2.BrickColor = BrickColor.new("Bright blue")
part2.Parent = model
model.PrimaryPart = part1
model.Parent = workspace
local obstruction = Instance.new("Part")
obstruction.Name = "Obstruction"
obstruction.Size = Vector3.new(10, 10, 10)
obstruction.Position = Vector3.new(0, 10, 0)
obstruction.Transparency = 0.5
obstruction.Anchored = true
obstruction.BrickColor = BrickColor.new("Bright green")
obstruction.Parent = workspace
task.wait(3)
-- use TranslateBy to shift the model into the obstruction
model:TranslateBy(END_POSITION - START_POSITION)

breakJoints

()
Deprecated

Returns

()

makeJoints

()
Deprecated

Returns

()

move

()
Deprecated

Parameters

location: Vector3
Default Value: ""

Returns

()

moveTo

()
Deprecated

Parameters

location: Vector3
Default Value: ""

Returns

()

Events

PersistentLoaded

This event fires every time a player has been sent all current persistent models and part-less atomic models. The player parameter indicates which player has received all applicable instances.

Note that experience loading happens before persistent loading, and firing of the DataModel.Loaded event does not indicate that all persistent models are present.

Parameters

player: Player