GeometryService

Show Deprecated
Not Creatable
Service

Service containing geometric operations not directly related to specific objects.

Summary

Methods

Properties

Methods

CalculateConstraintsToPreserve

Returns a table of Constraints and Attachments which you may choose to preserve, along with their respective parents. Iterating over this table lets you decide whether to reparent recommended constraints and attachments to their respective parents.

Note that the options table can contain a tolerance value (number) and/or a WeldConstraintPreserve value (Enum.WeldConstraintPreserve).

  • tolerance – The distance tolerance, in regards to Attachment preservation, between the attachment and the closest point on the original part's surface versus the closest point on the resulting part's surface. If the resulting distance following the solid modeling operation is greater than this value, the Parent of attachments and their associated constraints will be nil in the returned recommendation table.
  • weldConstraintPreserve – A Enum.WeldConstraintPreserve enum value describing how WeldConstraints are preserved in the resulting recommendation table.

Parameters

source: Instance

An original object that the solid modeling operation was performed on, for example part in UnionAsync().

destination: Array
options: Dictionary

Options table for the method:

  • tolerance – The distance tolerance, in regards to Attachment preservation, between the attachment and the closest point on the original part's surface versus the closest point on the resulting part's surface. If the resulting distance following the solid modeling operation is greater than this value, the Parent of attachments and their associated constraints will be nil in the returned recommendation table.
  • weldConstraintPreserve – A Enum.WeldConstraintPreserve enum value describing how WeldConstraints are preserved in the resulting recommendation table.
Default Value: "nil"

Returns

Table containing information for general case Constraints, NoCollisionConstraints, and WeldConstraints. In cases where an Attachment or Constraint should be dropped, its respective parent will be nil.

For general case Constraints such as HingeConstraint:

KeyType
AttachmentAttachment
ConstraintConstraint
AttachmentParentBasePart or nil
ConstraintParentBasePart or nil

For WeldConstraints:

KeyType
WeldConstraintWeldConstraint
WeldConstraintParentBasePart or nil
WeldConstraintPart0BasePart
WeldConstraintPart1BasePart

For NoCollisionConstraints:

KeyType
NoCollisionConstraintNoCollisionConstraint
NoCollisionConstraintParentBasePart or nil
NoCollisionConstraintPart0BasePart
NoCollisionConstraintPart1BasePart

Code Samples

Preserve Constraints

local GeometryService = game:GetService("GeometryService")
local mainPart = workspace.PurpleBlock
local otherParts = {workspace.BlueBlock}
local options = {
CollisionFidelity = Enum.CollisionFidelity.Default,
RenderFidelity = Enum.RenderFidelity.Automatic,
SplitApart = true
}
local constraintOptions = {
tolerance = 0.1,
weldConstraintPreserve = Enum.WeldConstraintPreserve.All
}
-- Perform subtract operation in pcall() since it's asyncronous
local success, newParts = pcall(function()
return GeometryService:SubtractAsync(mainPart, otherParts, options)
end)
if success and newParts then
-- Loop through resulting parts to reparent/reposition
for _, newPart in pairs(newParts) do
newPart.Parent = mainPart.Parent
newPart.CFrame = mainPart.CFrame
newPart.Anchored = mainPart.Anchored
end
-- Calculate constraints/attachments to either preserve or drop
local recommendedTable = GeometryService:CalculateConstraintsToPreserve(mainPart, newParts, constraintOptions)
-- Preserve constraints/attachments based on recommended table
for _, item in pairs(recommendedTable) do
if item.Attachment then
item.Constraint.Parent = item.ConstraintParent
item.Attachment.Parent = item.AttachmentParent
elseif item.NoCollisionConstraint then
local newNoCollision = Instance.new("NoCollisionConstraint")
newNoCollision.Part0 = item.NoCollisionPart0
newNoCollision.Part1 = item.NoCollisionPart1
newNoCollision.Parent = item.NoCollisionParent
elseif item.WeldConstraint then
local newWeldConstraint = Instance.new("WeldConstraint")
newWeldConstraint.Part0 = item.WeldConstraintPart0
newWeldConstraint.Part1 = item.WeldConstraintPart1
newWeldConstraint.Parent = item.WeldConstraintParent
end
end
-- Destroy original parts
mainPart.Parent = nil
mainPart:Destroy()
for _, otherPart in pairs(otherParts) do
otherPart.Parent = nil
otherPart:Destroy()
end
end

IntersectAsync

Yields

Creates one or more PartOperations from the intersecting geometry of the main part and other parts in the given array. Only primitive Parts and PartOperations are supported, not Terrain or MeshParts. Similar to Clone(), the returned parts have no set Parent.

The following properties from the main part (part) are applied to the resulting PartOperations:

In the following image comparison, IntersectAsync() is called using the purple block and an array containing the blue block. The resulting PartOperation 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 PartOperation

Notes

  • Compared to BasePart:IntersectAsync(), this method differs as follows:

    • The input parts do not need to be parented to the scene, allowing for background operations.
    • When the SplitApart option is set to true (default), each distinct body will be returned in its own PartOperation.
    • Each of the returned parts are in the coordinate space of the main part. This means that the (0, 0, 0) of any returned part is not necessarily at the center of its body.
    • It's possible to call this method on the client, but with some limitations. First, it currently must be done with objects created on the client. Secondly, there is no replication available from client to the server.
  • The original parts remain intact following a successful operation. In most cases, you should parent the returned PartOperations to the same place as the main part, then Destroy() all of the original parts.

  • By default, the face colors of the resulting PartOperations are borrowed from the Color property of the original parts, although you can enable their UsePartColor property to change them to a specific color.

  • If an intersect operation would result in any PartOperations with more than 20,000 triangles, they will be simplified to 20,000. This will result in an error with code -14.

  • If the main part is moving during the calculation of the operation, you can set the resulting parts to the updated CFrame of the main part, since the returned parts are in the same coordinate space as the main part.

  • If using this method with a PartOperation as the main part, you can substitute the geometry of another PartOperation via SubstituteGeometry(), making it easier to utilize the geometry of the operation but maintain properties, attributes, tags, and children of the main part such as Attachments, Constraints, ParticleEmitters, light objects, and decals. This approach also circumvents the potential "flicker" of completely replacing the original PartOperation with another.

Parameters

part: Instance

Main Part or PartOperation to operate on.

parts: Array

Array of parts to intersect with the main part.

options: Dictionary

Options table containing all the controls for the method:

  • CollisionFidelity – The value of CollisionFidelity in the resulting parts.
  • RenderFidelity – The value of RenderFidelity in the resulting parts.
  • FluidFidelity – The value of FluidFidelity in the resulting parts.
  • SplitApart – Boolean controlling whether the objects should all be kept together or properly split apart. Default is true (split).
Default Value: "nil"

Returns

One or more PartOperations from the intersecting geometry of the main part (part) and the other parts.

Code Samples

GeometryService:IntersectAsync()

local GeometryService = game:GetService("GeometryService")
local mainPart = workspace.PurpleBlock
local otherParts = {workspace.BlueBlock}
local options = {
CollisionFidelity = Enum.CollisionFidelity.Default,
RenderFidelity = Enum.RenderFidelity.Automatic,
SplitApart = true
}
-- Perform intersect operation in pcall() since it's asyncronous
local success, newParts = pcall(function()
return GeometryService:IntersectAsync(mainPart, otherParts, options)
end)
if success and newParts then
-- Loop through resulting parts to reparent/reposition
for _, newPart in pairs(newParts) do
newPart.Parent = mainPart.Parent
newPart.CFrame = mainPart.CFrame
newPart.Anchored = mainPart.Anchored
end
-- Destroy original parts
mainPart.Parent = nil
mainPart:Destroy()
for _, otherPart in pairs(otherParts) do
otherPart.Parent = nil
otherPart:Destroy()
end
end

SubtractAsync

Yields

Creates one or more PartOperations from the main part minus the geometry occupied by other parts in the given array. Only primitive Parts and PartOperations are supported, not Terrain or MeshParts. Similar to Clone(), the returned parts have no set Parent.

The following properties from the main part (part) are applied to the resulting PartOperations:

In the following image comparison, SubtractAsync() is called using the blue cylinder and an array containing the purple block. The resulting PartOperation 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 PartOperation

Notes

  • Compared to BasePart:SubtractAsync(), this method differs as follows:

    • The input parts do not need to be parented to the scene, allowing for background operations.
    • When the SplitApart option is set to true (default), each distinct body will be returned in its own PartOperation.
    • Each of the returned parts are in the coordinate space of the main part. This means that the (0, 0, 0) of any returned part is not necessarily at the center of its body.
    • It's possible to call this method on the client, but with some limitations. First, it currently must be done with objects created on the client. Secondly, there is no replication available from client to the server.
  • The original parts remain intact following a successful operation. In most cases, you should parent the returned PartOperations to the same place as the main part, then Destroy() all of the original parts.

  • By default, the face colors of the resulting PartOperations are borrowed from the Color property of the original parts, although you can enable their UsePartColor property to change them to a specific color.

  • If a subtract operation would result in any PartOperations with more than 20,000 triangles, they will be simplified to 20,000. This will result in an error with code -14.

  • If the main part is moving during the calculation of the operation, you can set the resulting parts to the updated CFrame of the main part, since the returned parts are in the same coordinate space as the main part.

  • If using this method with a PartOperation as the main part, you can substitute the geometry of another PartOperation via SubstituteGeometry(), making it easier to utilize the geometry of the operation but maintain properties, attributes, tags, and children of the main part such as Attachments, Constraints, ParticleEmitters, light objects, and decals. This approach also circumvents the potential "flicker" of completely replacing the original PartOperation with another.

Parameters

part: Instance

Main Part or PartOperation to operate on.

parts: Array

Array of parts to subtract from the main part.

options: Dictionary

Options table containing all the controls for the method:

  • CollisionFidelity – The value of CollisionFidelity in the resulting parts.
  • RenderFidelity – The value of RenderFidelity in the resulting parts.
  • FluidFidelity – The value of FluidFidelity in the resulting parts.
  • SplitApart – Boolean controlling whether the objects should all be kept together or properly split apart. Default is true (split).
Default Value: "nil"

Returns

One or more PartOperations from the geometry of the main part (part) minus the geometry occupied by the other parts.

Code Samples

GeometryService:SubtractAsync()

local GeometryService = game:GetService("GeometryService")
local mainPart = workspace.BlueCylinder
local otherParts = {workspace.PurpleBlock}
local options = {
CollisionFidelity = Enum.CollisionFidelity.Default,
RenderFidelity = Enum.RenderFidelity.Automatic,
SplitApart = true
}
-- Perform subtract operation in pcall() since it's asyncronous
local success, newParts = pcall(function()
return GeometryService:SubtractAsync(mainPart, otherParts, options)
end)
if success and newParts then
-- Loop through resulting parts to reparent/reposition
for _, newPart in pairs(newParts) do
newPart.Parent = mainPart.Parent
newPart.CFrame = mainPart.CFrame
newPart.Anchored = mainPart.Anchored
end
-- Destroy original parts
mainPart.Parent = nil
mainPart:Destroy()
for _, otherPart in pairs(otherParts) do
otherPart.Parent = nil
otherPart:Destroy()
end
end

UnionAsync

Yields

Creates one or more PartOperations from the main part plus the geometry occupied by other parts in the given array. Only primitive Parts and PartOperations are supported, not Terrain or MeshParts. Similar to Clone(), the returned parts have no set Parent.

The following properties from the main part (part) are applied to the resulting PartOperations:

In the following image comparison, UnionAsync() is called using the blue block and an array containing the purple cylinder. The resulting PartOperation 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 PartOperation

Notes

  • Compared to BasePart:UnionAsync(), this method differs as follows:

    • The input parts do not need to be parented to the scene, allowing for background operations.
    • When the SplitApart option is set to true (default), each distinct body will be returned in its own PartOperation.
    • Each of the returned parts are in the coordinate space of the main part. This means that the (0, 0, 0) of any returned part is not necessarily at the center of its body.
    • It's possible to call this method on the client, but with some limitations. First, it currently must be done with objects created on the client. Secondly, there is no replication available from client to the server.
  • The original parts remain intact following a successful operation. In most cases, you should parent the returned PartOperations to the same place as the main part, then Destroy() all of the original parts.

  • By default, the colors of the resulting PartOperations are borrowed from the Color property of the original parts, although you can enable their UsePartColor property to change them to a specific color.

  • If a union operation would result in any PartOperations with more than 20,000 triangles, they will be simplified to 20,000. This will result in an error with code -14.

  • If the main part is moving during the calculation of the operation, you can set the resulting parts to the updated CFrame of the main part, since the returned parts are in the same coordinate space as the main part.

  • If using this method with a PartOperation as the main part, you can substitute the geometry of another PartOperation via SubstituteGeometry(), making it easier to utilize the geometry of the operation but maintain properties, attributes, tags, and children of the main part such as Attachments, Constraints, ParticleEmitters, light objects, and decals. This approach also circumvents the potential "flicker" of completely replacing the original PartOperation with another.

Parameters

part: Instance

Main Part or PartOperation to operate on.

parts: Array

Array of parts to union with the main part.

options: Dictionary

Options table containing all the controls for the method:

  • CollisionFidelity – The value of CollisionFidelity in the resulting parts.
  • RenderFidelity – The value of RenderFidelity in the resulting parts.
  • FluidFidelity – The value of FluidFidelity in the resulting parts.
  • SplitApart – Boolean controlling whether the objects should all be kept together or properly split apart. Default is true (split).
Default Value: "nil"

Returns

One or more PartOperations from the geometry of the main part (part) plus the geometry occupied by the other parts.

Code Samples

GeometryService:UnionAsync()

local GeometryService = game:GetService("GeometryService")
local mainPart = workspace.BlueBlock
local otherParts = {workspace.PurpleCylinder}
local options = {
CollisionFidelity = Enum.CollisionFidelity.Default,
RenderFidelity = Enum.RenderFidelity.Automatic,
SplitApart = false
}
-- Perform union operation in pcall() since it's asyncronous
local success, newParts = pcall(function()
return GeometryService:UnionAsync(mainPart, otherParts, options)
end)
if success and newParts then
-- Loop through resulting parts to reparent/reposition
for _, newPart in pairs(newParts) do
newPart.Parent = mainPart.Parent
newPart.CFrame = mainPart.CFrame
newPart.Anchored = mainPart.Anchored
end
-- Destroy original parts
mainPart.Parent = nil
mainPart:Destroy()
for _, otherPart in pairs(otherParts) do
otherPart.Parent = nil
otherPart:Destroy()
end
end

Events