EditableMesh
EditableMesh changes the applied visual mesh when parented to a MeshPart, allowing for querying and modification of the mesh both in Studio and in experience.
An EditableMesh can be created from an existing mesh ID using AssetService:CreateEditableMeshAsync(), or a blank EditableMesh can be created with Instance.new(). 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.
An EditableMesh is displayed when it's parented to a MeshPart, but only the part's appearance changes while the collision model remains the same.
Stable Vertex/Face IDs
Many EditableMesh methods take vertex 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 GetTriangles().
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.
Limitations
EditableMesh currently has a limit of 60,000 vertices and 20,000 triangles. Attempting to add too many vertices or triangles will cause an error.
Summary
Properties
The Offset of a mesh determines the relative position from the BasePart.Position of a BasePart that the mesh will be displayed at.
The Scale of a mesh determines the size of the mesh relative to its original dimensions.
Changes the hue of a mesh's texture, used with FileMesh.TextureId.
Methods
Adds a new triangle to the mesh and returns a stable triangle ID.
Adds a new vertex to the geometry and returns a stable vertex ID.
Finds the closest point on the mesh's surface.
Finds the closest vertex to a specific point in space.
Finds all vertices within a specific sphere.
Returns a list of vertices adjacent to a given vertex.
Gets the position of a vertex.
Returns UV coordinates at the given vertex.
Returns all vertices as a list of stable vertex IDs.
Sets a vertex position in the mesh's local object space.
Sets UV coordinates for a vertex.
Properties
SkinningEnabled
Methods
AddTriangle
Adds a new triangle to the mesh and returns a stable triangle ID.
Parameters
ID of the first vertex of the triangle.
ID of the second vertex of the triangle.
ID of the third vertex of the triangle.
Returns
AddVertex
Adds a new vertex to the geometry and returns a stable vertex ID.
Parameters
Position in the mesh's local object space.
Returns
Stable ID of the new vertex.
FindClosestPointOnSurface
Finds the closest point on the mesh's surface. Returns the triangle ID, point on the mesh in local object space, and the barycentric coordinate of the position within the triangle. See RaycastLocal() for more information on barycentric coordinates.
Parameters
Point position in the mesh's local object space.
Returns
Tuple of the triangle ID, point on the mesh in local object space, and the barycentric coordinate of the position within the triangle.
FindClosestVertex
Finds the closest vertex to a specific point in space and returns a stable vertex ID.
Parameters
Point position in the mesh's local object space.
Returns
Closest stable vertex ID to the specified point in space.
FindVerticesWithinSphere
Finds all vertices within a specific sphere and returns a list of stable vertex IDs.
Parameters
Center of the sphere in the mesh's local object space.
Radius of the sphere.
Returns
List of stable vertex IDs within the requested sphere.
GetAdjacentVertices
Given a stable vertex ID, returns a list of adjacent vertices.
Parameters
Vertex ID around which to get adjacent vertices.
Returns
List of IDs of adjacent vertices around the given vertex ID.
GetPosition
Gets the position of a vertex in the mesh's local object space.
Parameters
Stable vertex ID for which to get the position.
Returns
Position of a vertex in the mesh's local object space.
GetUV
Returns UV coordinates at the given vertex.
Parameters
Returns
UV coordinates at the requested vertex.
GetVertices
Returns all vertices as a list of stable vertex IDs.
Returns
List of stable vertex IDs.
RaycastLocal
Casts a ray and returns a point of intersection, triangle ID, and barycentric coordinates. The inputs and outputs of this method are in the mesh's local object space.
A barycentric coordinate is a way of specifying a point within a triangle as a weighted combination of the 3 vertices of the triangle. This is useful as a general way of blending vertex attributes. See this method's code sample as an illustration.
Parameters
Origin of the ray in the mesh's local object space.
Direction of the ray.
Returns
Tuple of the point of intersection, triangle ID, and barycentric coordinates.
Code Samples
local AssetService = game:GetService("AssetService")
local meshPart = Instance.new("MeshPart")
meshPart.Parent = workspace
-- Initialize EditableMesh in space
local success, editableMesh = pcall(function()
return AssetService:CreateEditableMeshAsync("rbxassetid://ASSET_ID")
end)
if success then
editableMesh.Parent = meshPart
end
local function castRayFromCamera(position)
if not editableMesh then return end
-- Create ray from camera along the direction of a clicked point
local camera = workspace.CurrentCamera
local ray = camera:ScreenPointToRay(position.X, position.Y)
-- Convert to object space to use with RaycastLocal()
local relativeOrigin = meshPart.CFrame:PointToObjectSpace(ray.Origin)
local relativeDirection = meshPart.CFrame:VectorToObjectSpace(ray.Direction)
local triangleId, point, barycentricCoordinate
triangleId, point, barycentricCoordinate = editableMesh:RaycastLocal(relativeOrigin, relativeDirection * 100)
if not triangleId then
-- Didn't hit any triangles
return
end
-- Interpolate UVs within the triangle
local vert1, vert2, vert3 = editableMesh:GetTriangleVertices(triangleId)
local uv0 = editableMesh:GetUV(vert1)
local uv1 = editableMesh:GetUV(vert2)
local uv2 = editableMesh:GetUV(vert3)
local u = (barycentricCoordinate.x * uv0.x) + (barycentricCoordinate.y * uv1.x) + (barycentricCoordinate.z * uv2.x)
local v = (barycentricCoordinate.x * uv0.y) + (barycentricCoordinate.y * uv1.y) + (barycentricCoordinate.z * uv2.y)
return Vector2.new(u, v)
end
SetPosition
Sets a vertex position in the mesh's local object space.
Parameters
Stable ID of the vertex to position.
Position in the mesh's local object space.
Returns
SetUV
Sets UV coordinates for a vertex.