EditableMesh¶
Object which allows for the runtime creation and manipulation of meshes.
Not implemented yet
Runtime mesh editing is not implemented.
Description¶
EditableMesh changes the applied visual mesh when linked to a
MeshPart, allowing for querying and modification of the mesh both in
Studio and in-game.
Enabling for published games¶
For security purposes, using EditableMesh fails by default in published
games. To enable it, open the
Creator Dashboard, go to the
game's Configure ⟩ Settings, and toggle on Enable Mesh / Image
APIs. Alternatively, in Studio, open Experience Settings and toggle on
Allow Mesh / Image APIs under Security. Remember to review the
Terms of Use
before enabling the toggle.
Permissions¶
To prevent misuse, AssetService.CreateEditableMeshAsync() only allows you to load and edit mesh assets if any of the following is true:
- Owned by or explicitly shared with the game owner.
- Owned by or explicitly shared with the logged in Studio user.
- Owned by or explicitly shared with the logged in player if the
EditableMeshis on the client side. - Owned by a group where the game owner, Studio user, or player has a role with permission to edit the group's assets. See Roles and permissions for more information.
See Grant permissions to learn how to share assets with users or groups.
The APIs throw an error if they are used to load an asset that does not meet the criteria above.
Memory limits¶
Editable assets are currently expensive for memory usage. To minimize its
impact on client performance, EditableMesh has strict client-side memory
budgets, although the server, Studio, and plugins operate with unlimited
memory. Using FixedSize may help you stay
within the memory budget and, in some scenarios, linking one EditableMesh to
multiple MeshParts (multi-referencing) can help with memory
optimization.
Creation and display¶
An EditableMesh can be created from an existing Content of a
MeshPart or a mesh ID using
AssetService.CreateEditableMeshAsync(), or a blank EditableMesh can
be created with AssetService.CreateEditableMesh(). It can then be
displayed, modified, and its collision model updated. Not all of the steps are
necessary; for example, you might want to create an EditableMesh just to
raycast without ever displaying it.
local AssetService = game:GetService("AssetService")
-- Create empty EditableMesh
local editableMesh = AssetService:CreateEditableMesh()
-- Create EditableMesh from asset ID
local editableMeshFromAsset = nil
local success, errorMessage = pcall(function()
editableMeshFromAsset = AssetService:CreateEditableMeshAsync(Content.fromAssetId(ASSET_ID))
end)
-- Create EditableMesh from another EditableMesh
local editableMeshFromAnother = nil
local success, errorMessage = pcall(function()
editableMeshFromAnother = AssetService:CreateEditableMeshAsync(Content.fromObject(OTHER_EDITABLE_MESH))
end)
-- Create EditableMesh from MeshPart
local editableMeshFromMeshPart = nil
local success, errorMessage = pcall(function()
editableMeshFromMeshPart = AssetService:CreateEditableMeshAsync(MESH_PART.MeshContent)
end)
An EditableMesh is displayed when it's linked to a new MeshPart,
through AssetService.CreateMeshPartAsync(). You can create more
MeshPart instances that reference the same EditableMesh
Content, or link to an existing MeshPart through
MeshPart.ApplyMesh().
local AssetService = game:GetService("AssetService")
local Workspace = game:GetService("Workspace")
-- Create EditableMesh from asset ID
local editableMeshFromAsset = nil
local success, errorMessage = pcall(function()
editableMeshFromAsset = AssetService:CreateEditableMeshAsync(Content.fromAssetId(ASSET_ID))
end)
-- Create new MeshPart linked to the EditableMesh
local newMeshPart = nil
local success, errorMessage = pcall(function()
newMeshPart = AssetService:CreateMeshPartAsync(Content.fromObject(editableMeshFromAsset))
end)
-- Alternatively, link the new MeshPart created above to an existing MeshPart
local existingMeshPart = Workspace:FindFirstChild("EXISTING_MESH_PART")
existingMeshPart:ApplyMesh(newMeshPart)
To recalculate collision and fluid geometry after editing, you can again call AssetService.CreateMeshPartAsync() and MeshPart.ApplyMesh() to update an existing MeshPart. It's generally recommended to do this at the end of a conceptual edit, not after individual calls to methods that manipulate geometry. Visual changes to the mesh will always be immediately reflected by the engine, without the need to call AssetService.CreateMeshPartAsync().
Fixed-size meshes¶
When creating an EditableMesh from an existing mesh asset (via
AssetService.CreateEditableMeshAsync()), the resulting editable mesh
is fixed-size by default. Fixed-size meshes are more efficient in terms of
memory but you cannot change the number of vertices, faces, or attributes.
Only the values of vertex attributes and positions can be edited.
local AssetService = game:GetService("AssetService")
-- Create EditableMesh without fixed-size default
local editableMeshFromAsset = nil
local success, errorMessage = pcall(function()
editableMeshFromAsset = AssetService:CreateEditableMeshAsync(Content.fromAssetId(ASSET_ID), {FixedSize = false})
end)
Stable IDs¶
Many EditableMesh methods take vertex, normal, UV, color and
face IDs. These are represented as integers in Luau but they require some
special handling. The main difference is that IDs are stable and they remain
the same even if other parts of the mesh change. For example, if an
EditableMesh has five vertices {1, 2, 3, 4, 5} and you remove vertex 4,
the new vertices will be {1, 2, 3, 5}.
Note that the IDs are not guaranteed to be in order and there may be holes in the numbering, so when iterating through vertices or faces, you should iterate through the table returned by GetVertices() or GetFaces().
For debugging purposes, it can be very helpful to get a more readable string for a stable ID with IdDebugString().
Split vertex attributes¶
A vertex is a corner of a face, and topologically connects faces together. Each vertex has a single position, while its normal, UV coordinate, and color (with transparency) are stored per face corner. A vertex shared by multiple faces can use the same values on every face, or different values on each.
Sometimes it's useful for all faces that touch a vertex to use the same attribute values, but sometimes you'll want different faces to use different attribute values on the same vertex. For example, on a smooth sphere, each vertex will only have a single normal. In contrast, at the corner of a cube, the vertex will have 3 different normals (one for each adjacent face). You can also have seams in the UV coordinates or sharp changes in the vertex colors.
When creating faces with AddFace() or
AddTriangle(), each corner of the new face
is automatically assigned a normal, UV, and color attribute. If a vertex
already belongs to an existing face, the new face reuses that vertex's
existing attributes (producing smooth shading and continuous UVs). If the
vertex is new, fresh attribute IDs are created with default values
(auto-computed normal, UV of (0, 0), white color). To create a seam, you
should create new attributes and set them on the face. For example, this code
will create a sharp cube:
local AssetService = game:GetService("AssetService")
-- Given 4 vertex IDs, adds a new normal and a quad face, making a sharp quad
local function addSharpQuad(editableMesh, vid0, vid1, vid2, vid3)
local nid = editableMesh:AddNormal() -- This creates a normal ID which is automatically computed
local fid = editableMesh:AddFace(vid0, vid1, vid2, vid3)
editableMesh:SetFaceNormals(fid, {nid, nid, nid, nid})
end
-- Makes a cube with creased edges between the 6 sides
local function makeSharpCube()
local editableMesh = AssetService:CreateEditableMesh()
local v1 = editableMesh:AddVertex(Vector3.new(0, 0, 0))
local v2 = editableMesh:AddVertex(Vector3.new(1, 0, 0))
local v3 = editableMesh:AddVertex(Vector3.new(0, 1, 0))
local v4 = editableMesh:AddVertex(Vector3.new(1, 1, 0))
local v5 = editableMesh:AddVertex(Vector3.new(0, 0, 1))
local v6 = editableMesh:AddVertex(Vector3.new(1, 0, 1))
local v7 = editableMesh:AddVertex(Vector3.new(0, 1, 1))
local v8 = editableMesh:AddVertex(Vector3.new(1, 1, 1))
addSharpQuad(editableMesh, v5, v6, v8, v7) -- Front
addSharpQuad(editableMesh, v1, v3, v4, v2) -- Back
addSharpQuad(editableMesh, v1, v5, v7, v3) -- Left
addSharpQuad(editableMesh, v2, v4, v8, v6) -- Right
addSharpQuad(editableMesh, v1, v2, v6, v5) -- Bottom
addSharpQuad(editableMesh, v3, v7, v8, v4) -- Top
editableMesh:RemoveUnused()
return editableMesh
end
Winding¶
Mesh faces have a front side and a back side. When drawing meshes, only the
front of the faces are drawn by default, although you can change this by
setting the mesh' DoubleSided property to true.
The order of the vertices around the face determines whether you are looking at the front or the back. The front of the face is visible when the vertices go counterclockwise around it.

FACS poses¶
Animatable heads use the Facial Action Coding System (FACS). See the FACS poses reference for helpful information when using GetFacsPoses() and similar methods.
Each FACS pose is specified by an FacsActionUnit value. For the FACS pose, virtual bones can each have a CFrame that transforms the bones' initial CFrame in the bind pose of the mesh into the CFrame for that FACS action unit's pose. All bone CFrames are in the mesh's local space.
These FACS poses are blended together during animation. Sometimes, the blending of the base poses produces poor results. In those cases, you can override the blending of specific combinations of base poses with a corrective pose that is more pleasing. A corrective pose is specified by 2 or 3 FacsActionUnit values. Like a base FACS pose, for a corrective pose, virtual bones can each have a CFrame that transforms the bones' initial CFrame in the bind pose of the mesh into the CFrame for that FACS corrective.
Please note that corrective poses that operate on both left and right action
units are not currently expressible. For example, using LeftCheekPuff and
RightEyeClosed together in a corrective pose is not currently possible.
Batching¶
The batch methods let you create, read, update, and remove many mesh elements in a single call instead of invoking the singular methods (AddVertex(), SetPosition(), GetColor(), and so on) once per element. Batching your mesh operations is typically much more performant than handling them one by one.
Rather than one method per attribute, each batch method shares a small set of general entry points and uses an MeshAttribute value (or the type already encoded in each mesh ID) to determine which attribute you mean. For example, BatchSetValues() sets positions when called with vertex IDs, but sets normals when called with normal IDs. You cannot mix-and-match ID types within a single call.
Batch setters take parallel arrays: element i of every argument array
describes the same logical operation. In
Class.EditableMesh:BatchSetValues()|BatchSetValues(ids, values), values[i]
is written to ids[i]. All argument arrays must be the same length or the
call errors. Batch getters take an array of IDs and return results in the same
order.
If a mesh ID is invalid, batching still applies updates to all elements before the invalid ID, then stops.
Limitations¶
EditableMesh currently has a limit of 60,000 vertices and 20,000 triangles.
Faces can be triangles or quads, and each quad counts as 2 triangles toward
the triangle limit. Attempting to add too many vertices or triangles will
cause an error.
Inheritance¶
Object → EditableMesh
Properties¶
| Member | Signature | Summary |
|---|---|---|
EditableMeshDataHolder |
EditableMeshDataHolder: NetAssetRef |
— |
FixedSize |
FixedSize: bool |
Returns true if a mesh is fixed-size. |
IsReplicatedCopy |
IsReplicatedCopy: bool |
— |
MeshData |
MeshData: SharedString |
— |
Methods¶
| Member | Signature | Summary |
|---|---|---|
AddBone |
EditableMesh:AddBone(boneProperties: Dictionary): int64 |
Adds a new bone and returns a bone ID. |
AddColor |
EditableMesh:AddColor(color: Color3, alpha: float): int64 |
Adds a new color to the geometry and returns a color ID. |
AddFace |
EditableMesh:AddFace(vertexIds: Array): int64 |
Adds a new triangle or quad face to the mesh and returns a face ID. |
AddNormal |
EditableMesh:AddNormal(normal: Vector3?): int64 |
Adds a new normal to the geometry and returns a normal ID. |
AddTriangle |
EditableMesh:AddTriangle(vertexId0: int64, vertexId1: int64, vertexId2: int64): int64 |
Adds a new triangle to the mesh and returns a face ID. |
AddUV |
EditableMesh:AddUV(uv: Vector2): int64 |
Adds a new UV to the geometry and returns a UV ID. |
AddVertex |
EditableMesh:AddVertex(p: Vector3): int64 |
Adds a new vertex to the geometry and returns a vertex ID. |
BatchAdd |
EditableMesh:BatchAdd(attr: MeshAttribute, data: Array): Array |
Creates new mesh elements of the given attribute type and returns their IDs. |
BatchGetFaceAttributes |
EditableMesh:BatchGetFaceAttributes(attr: MeshAttribute, faceIds: Array): Array |
Returns the per-corner attribute IDs for each face in a batch. |
BatchGetValues |
EditableMesh:BatchGetValues(ids: Array): Tuple |
Returns attribute values for each ID in a batch. |
BatchGetVertexAttributes |
EditableMesh:BatchGetVertexAttributes(attr: MeshAttribute, vertexIds: Array): Array |
Returns the attribute IDs associated with each vertex in a batch. |
BatchGetVertexFaceAttributes |
EditableMesh:BatchGetVertexFaceAttributes(attr: MeshAttribute, vertexIds: Array, faceIds: Array): Array |
Returns the attribute ID at each specified corner for a batch of vertex–face pairs. |
BatchRemove |
EditableMesh:BatchRemove(ids: Array): null |
Removes a batch of faces. |
BatchSetFaceAttributes |
EditableMesh:BatchSetFaceAttributes(faceIds: Array, attrIdArrays: Array): null |
Sets the per-corner attribute IDs for each face in a batch. |
BatchSetValues |
EditableMesh:BatchSetValues(ids: Array, values: Array): null |
Writes attribute values to a batch of mesh element IDs. |
BatchSetVertexFaceAttributes |
EditableMesh:BatchSetVertexFaceAttributes(vertexIds: Array, faceIds: Array, attrIds: Array): null |
Sets the attribute at a specific corner for each vertex–face pair in a batch. |
Clear |
EditableMesh:Clear(): null |
Clears all of an EditableMesh's geometry. |
Destroy |
EditableMesh:Destroy(): null |
Destroys the mesh. |
FindClosestPointOnSurface |
EditableMesh:FindClosestPointOnSurface(point: Vector3): Tuple |
Finds the closest point on the mesh's surface. |
FindClosestVertex |
EditableMesh:FindClosestVertex(toThisPoint: Vector3): int64 |
Finds the closest vertex to a specific point in space. |
FindVerticesWithinSphere |
EditableMesh:FindVerticesWithinSphere(center: Vector3, radius: float): Array |
Finds all vertices within a specific sphere. |
GetAdjacentFaces |
EditableMesh:GetAdjacentFaces(faceId: int64): Array |
Returns a list of faces adjacent to a given face. |
GetAdjacentVertices |
EditableMesh:GetAdjacentVertices(vertexId: int64): Array |
Returns a list of vertices adjacent to a given vertex. |
GetBoneByName |
EditableMesh:GetBoneByName(boneName: string): int64 |
Finds the bone ID of the bone with the given name. |
GetBoneCFrame |
EditableMesh:GetBoneCFrame(boneId: int64): CFrame |
Returns the initial CFrame of the bone in the bind pose of the mesh. |
GetBoneIsVirtual |
EditableMesh:GetBoneIsVirtual(boneId: int64): bool |
Returns true if the bone is virtual. |
GetBoneName |
EditableMesh:GetBoneName(boneId: int64): string |
Returns the bone name. |
GetBoneParent |
EditableMesh:GetBoneParent(boneId: int64): int64 |
Returns the parent bone ID, if any. |
GetBones |
EditableMesh:GetBones(): Array |
Returns all bones of the mesh. |
GetCenter |
EditableMesh:GetCenter(): Vector3 |
Returns the center of the mesh's axis-aligned bounding box. |
GetColor |
EditableMesh:GetColor(colorId: int64): Color3? |
Returns the color for the given color ID. |
GetColorAlpha |
EditableMesh:GetColorAlpha(colorId: int64): float? |
Returns the color alpha (transparency) at the given color ID. |
GetColors |
EditableMesh:GetColors(): Array |
Returns all colors of the mesh. |
GetFaceColors |
EditableMesh:GetFaceColors(faceId: int64): Array |
Returns the face's color IDs for the vertices on the face. |
GetFaceNormals |
EditableMesh:GetFaceNormals(faceId: int64): Array |
Returns the face's normal IDs for the vertices on the face. |
GetFaces |
EditableMesh:GetFaces(): Array |
Returns all faces of the mesh. |
GetFacesWithAttribute |
EditableMesh:GetFacesWithAttribute(id: int64): Array |
Returns a list of faces that use a given attribute ID. |
GetFacesWithColor |
EditableMesh:GetFacesWithColor(colorId: int64): Array |
Returns an array of face IDs that use the given color ID. |
GetFacesWithNormal |
EditableMesh:GetFacesWithNormal(normalId: int64): Array |
Returns an array of face IDs that use the given normal ID. |
GetFacesWithUV |
EditableMesh:GetFacesWithUV(uvId: int64): Array |
Returns an array of face IDs that use the given UV ID. |
GetFaceUVs |
EditableMesh:GetFaceUVs(faceId: int64): Array |
Returns the face's UV IDs for the vertices on the face. |
GetFaceVertices |
EditableMesh:GetFaceVertices(faceId: int64): Array |
Returns the face's vertex IDs. |
GetFacsCorrectivePose |
EditableMesh:GetFacsCorrectivePose(actions: Array): Tuple |
Returns bone IDs and bone CFrames for all bones in a specific FACS corrective pose. |
GetFacsCorrectivePoses |
EditableMesh:GetFacsCorrectivePoses(): Array |
Returns all FACS corrective poses that are in use. |
GetFacsPose |
EditableMesh:GetFacsPose(action: FacsActionUnit): Tuple |
Returns bone IDs and bone CFrames for all bones in a specific FACS action unit. |
GetFacsPoses |
EditableMesh:GetFacsPoses(): Array |
Returns all FACS action units that have poses defined. |
GetNormal |
EditableMesh:GetNormal(normalId: int64): Vector3? |
Returns the normal vector for the given normal ID. |
GetNormals |
EditableMesh:GetNormals(): Array |
Returns all normals of the mesh. |
GetPosition |
EditableMesh:GetPosition(vertexId: int64): Vector3 |
Gets the position of a vertex. |
GetSize |
EditableMesh:GetSize(): Vector3 |
Returns the size of the mesh's axis-aligned bounding box. |
GetUV |
EditableMesh:GetUV(uvId: int64): Vector2? |
Returns UV coordinates at the given UV ID. |
GetUVs |
EditableMesh:GetUVs(): Array |
Returns all UVs of the mesh. |
GetVertexBones |
EditableMesh:GetVertexBones(vertexId: int64): Array |
Returns all bone IDs that are associated with the vertex for skinning. |
GetVertexBoneWeights |
EditableMesh:GetVertexBoneWeights(vertexId: int64): Array |
Returns skinning blend weights for each bone that is associated with the vertex. |
GetVertexColors |
EditableMesh:GetVertexColors(vertexId: int64): Array |
Returns the color IDs of the faces attached to the given vertex. |
GetVertexFaceColor |
EditableMesh:GetVertexFaceColor(vertexId: int64, faceId: int64): int64 |
Returns the color ID of a vertex/face pair. |
GetVertexFaceNormal |
EditableMesh:GetVertexFaceNormal(vertexId: int64, faceId: int64): int64 |
Returns the normal ID of a vertex/face pair. |
GetVertexFaces |
EditableMesh:GetVertexFaces(vertexId: int64): Array |
Returns the face IDs of the faces attached to the given vertex. |
GetVertexFaceUV |
EditableMesh:GetVertexFaceUV(vertexId: int64, faceId: int64): int64 |
Returns the UV ID of a vertex/face pair. |
GetVertexNormals |
EditableMesh:GetVertexNormals(vertexId: int64): Array |
Returns the normal IDs of the faces attached to the given vertex. |
GetVertexUVs |
EditableMesh:GetVertexUVs(vertexId: int64): Array |
Returns the UV IDs of the faces attached to the given vertex. |
GetVertices |
EditableMesh:GetVertices(): Array |
Returns all vertices as a list of vertex IDs. |
GetVerticesWithAttribute |
EditableMesh:GetVerticesWithAttribute(id: int64): Array |
Returns a list of vertices that use a given attribute ID. |
GetVerticesWithColor |
EditableMesh:GetVerticesWithColor(colorId: int64): Array |
Returns an array of vertex IDs that use the given color ID. |
GetVerticesWithNormal |
EditableMesh:GetVerticesWithNormal(normalId: int64): Array |
Returns an array of vertex IDs that use the given normal ID. |
GetVerticesWithUV |
EditableMesh:GetVerticesWithUV(uvId: int64): Array |
Returns an array of vertex IDs that use the given UV ID. |
IdDebugString |
EditableMesh:IdDebugString(id: int64): string |
Returns a string describing an ID, useful for debugging purposes. |
MergeVertices |
EditableMesh:MergeVertices(mergeTolerance: float): Map |
Merges vertices that touch together. |
RaycastLocal |
EditableMesh:RaycastLocal(origin: Vector3, direction: Vector3): Tuple |
Casts a ray and returns the intersection point, face ID, and barycentric coordinates. |
RemoveBone |
EditableMesh:RemoveBone(boneId: int64): null |
Removes a bone using its bone ID. |
RemoveFace |
EditableMesh:RemoveFace(faceId: int64): null |
Removes a face using its face ID. |
RemoveUnused |
EditableMesh:RemoveUnused(): Array |
Removes all unused vertices, normals, UVs, and colors, and returns the removed IDs. |
ResetNormal |
EditableMesh:ResetNormal(normalId: int64): null |
Reset this normal ID to be automatically calculated. |
SetBoneCFrame |
EditableMesh:SetBoneCFrame(boneId: int64, cframe: CFrame): null |
Set the initial CFrame for a bone in the mesh's bind pose. |
SetBoneIsVirtual |
EditableMesh:SetBoneIsVirtual(boneId: int64, virtual: bool): null |
Set whether a bone is virtual. |
SetBoneName |
EditableMesh:SetBoneName(boneId: int64, name: string): null |
Sets the name for a bone. |
SetBoneParent |
EditableMesh:SetBoneParent(boneId: int64, parentBoneId: int64): null |
Set a parent for a bone. |
SetColor |
EditableMesh:SetColor(colorId: int64, color: Color3): null |
Sets the color for a color ID. |
SetColorAlpha |
EditableMesh:SetColorAlpha(colorId: int64, alpha: float): null |
Sets the color alpha (transparency) for a color ID. |
SetFaceColors |
EditableMesh:SetFaceColors(faceId: int64, ids: Array): null |
Sets the face's vertex colors to new color IDs. |
SetFaceNormals |
EditableMesh:SetFaceNormals(faceId: int64, ids: Array): null |
Sets the face's vertex normals to new normal IDs. |
SetFaceUVs |
EditableMesh:SetFaceUVs(faceId: int64, ids: Array): null |
Sets the face's vertex UVs to new UV IDs. |
SetFaceVertices |
EditableMesh:SetFaceVertices(faceId: int64, ids: Array): null |
Sets the face's vertices to new vertex IDs. |
SetFacsBonePose |
EditableMesh:SetFacsBonePose(action: FacsActionUnit, boneId: int64, cframe: CFrame): null |
Set CFrame for an individual bone in a specific FACS action unit. |
SetFacsCorrectivePose |
EditableMesh:SetFacsCorrectivePose(actions: Array, boneIds: Array, cframes: Array): null |
Set pose for all bones in a specific FACS corrective pose. |
SetFacsPose |
EditableMesh:SetFacsPose(action: FacsActionUnit, boneIds: Array, cframes: Array): null |
Set pose for all bones in a specific FACS action unit. |
SetNormal |
EditableMesh:SetNormal(normalId: int64, normal: Vector3): null |
Set the normal for a normal ID. |
SetPosition |
EditableMesh:SetPosition(vertexId: int64, p: Vector3): null |
Sets a vertex position in the mesh's local object space. |
SetUV |
EditableMesh:SetUV(uvId: int64, uv: Vector2): null |
Sets UV coordinates for a UV ID. |
SetVertexBones |
EditableMesh:SetVertexBones(vertexId: int64, boneIDs: Array): null |
Assign a list of bones with the vertex for skinning. |
SetVertexBoneWeights |
EditableMesh:SetVertexBoneWeights(vertexId: int64, boneWeights: Array): null |
Sets skinning blend weights for each bone associated with the vertex. |
SetVertexFaceColor |
EditableMesh:SetVertexFaceColor(vertexId: int64, faceId: int64, colorId: int64): null |
Sets the color ID of a vertex/face pair. |
SetVertexFaceNormal |
EditableMesh:SetVertexFaceNormal(vertexId: int64, faceId: int64, normalId: int64): null |
Sets the normal ID of a vertex/face pair. |
SetVertexFaceUV |
EditableMesh:SetVertexFaceUV(vertexId: int64, faceId: int64, uvId: int64): null |
Sets the UV ID of a vertex/face pair. |
Triangulate |
EditableMesh:Triangulate(): null |
Splits all faces on the mesh to be triangles. |
Roblox reference: EditableMesh
Generated from Nova's API dump and Roblox creator-docs. Nova-only members come from the engine's reflection metadata.