EditableMesh
*Dieser Inhalt wurde mit KI (Beta) übersetzt und kann Fehler enthalten. Um diese Seite auf Englisch zu sehen, klicke hier.
EditableMesh ändert die angewendete visuelle Mesh, wenn es mit einem MeshPart verbunden wird, und ermöglicht die Anfrage und Änderung der Mesh sowohl in Studio als auch im Erlebnis.
Aktivieren für veröffentlichte Erlebnisse
Zum Sicherheitszweck scheitert die Verwendung von EditableMesh für veröffentlichte Erlebnisse standardmäßig.Um die Nutzung zu aktivieren, musst du verifiziert sein 13+ Alter und ID verifiziert.Nachdem du verifiziert wurdest, öffne Studio's Spieleinstellungen, wähle Sicherheit aus und aktiviere den Allow Mesh / Image APIs Schalter.
Berechtigungen
Um Missbrauch zu verhindern, erlaubt AssetService:CreateEditableMeshAsync() nur das Laden und Bearbeiten von Mesh-Assets:
- Diese gehören dem Ersteller des Erlebnisses (wenn das Erlebnis von einer Person besessen wird).
- Diese gehören einer Gruppe (wenn das Erlebnis der Gruppe gehört).
- Diese gehören dem angemeldeten Studio-Benutzer (wenn die Platzdatei noch nicht auf Roblox gespeichert oder veröffentlicht wurde).
Speichergrenzen
Bearbeitbare Assets sind derzeit teuer für die Speicherverwendung.Um seine Auswirkungen auf die Client-Leistung zu minimieren, hat EditableMesh strenge Client-Speicherbudgets, obwohl der Server, Studio und Plugins mit unbegrenztem Speicher arbeiten.Die Verwendung von FixedSize kann Ihnen helfen, innerhalb des Speicherbudgets zu bleiben, und in einigen Szenarien kann das Verknüpfen einer EditableMesh mit mehreren MeshParts (Multi-Referenz) bei der Speicheroptimierung helfen.
Erstellung und Anzeige
Ein EditableMesh kann aus einem vorhandenen Content eines MeshPart oder einer Mesh-ID mit AssetService:CreateEditableMeshAsync() erstellt werden, oder ein leeres EditableMesh kann mit AssetService:CreateEditableMesh() erstellt werden.Es kann dann angezeigt, modifiziert und sein Kollisionsmodell aktualisiert werden.Nicht alle Schritte sind notwendig; zum Beispiel möchten Sie vielleicht ein EditableMesh erstellen, um es nur zu raycasten, ohne es jemals anzuzeigen.
local AssetService = game:GetService("AssetService")
-- Leeres bearbeitbares Netz erstellen
local editableMesh = AssetService:CreateEditableMesh()
-- Erstellen von bearbeitbarem Netz aus Asset-ID
local editableMeshFromAsset = nil
local success, errorMessage = pcall(function()
editableMeshFromAsset = AssetService:CreateEditableMeshAsync(Content.fromAssetId(ASSET_ID))
end)
-- Erstellen von bearbeitbarem Netz aus einem anderen bearbeitbaren Netz
local editableMeshFromAnother = nil
local success, errorMessage = pcall(function()
editableMeshFromAnother = AssetService:CreateEditableMeshAsync(Content.fromObject(OTHER_EDITABLE_MESH))
end)
-- Erstellen von bearbeitbaren Meshes aus MeshPart
local editableMeshFromMeshPart = nil
local success, errorMessage = pcall(function()
editableMeshFromMeshPart = AssetService:CreateEditableMeshAsync(MESH_PART.MeshContent)
end)
Ein EditableMesh wird angezeigt, wenn es mit einem neuen MeshPart verbunden ist, durch AssetService:CreateMeshPartAsync() .Du kannst mehr Instanzen erstellen, die auf dasselbe referenzieren oder auf eine bestehende durch verlinken.
local AssetService = game:GetService("AssetService")
local Workspace = game:GetService("Workspace")
-- Erstellen von bearbeitbarem Netz aus Asset-ID
local editableMeshFromAsset = nil
local success, errorMessage = pcall(function()
editableMeshFromAsset = AssetService:CreateEditableMeshAsync(Content.fromAssetId(ASSET_ID))
end)
-- Erstellen Sie ein neues MeshPart, das mit dem bearbeitbaren Mesh verbunden ist
local newMeshPart = nil
local success, errorMessage = pcall(function()
newMeshPart = AssetService:CreateMeshPartAsync(Content.fromObject(editableMeshFromAsset))
end)
-- Alternativ verknüpfe das neue MeshPart, das oben erstellt wurde, mit einem bestehenden MeshPart
local existingMeshPart = Workspace:FindFirstChild("EXISTING_MESH_PART")
existingMeshPart:ApplyMesh(newMeshPart)
Um die Kollision und Fluidgeometrie nach der Bearbeitung wieder neu zu berechnen, kannst du erneut AssetService:CreateMeshPartAsync() und MeshPart:ApplyMesh() anrufen, um eine vorhandene MeshPart zu aktualisieren.Es wird in der Regel empfohlen, dies am Ende einer konzeptionellen Bearbeitung zu tun, nicht nach einzelnen Anrufen von Methoden, die Geometrie manipulieren.Visuelle Änderungen am Mesh werden immer sofort von der Engine reflektiert, ohne dass AssetService:CreateMeshPartAsync() aufgerufen werden muss.
Fixierte Größenmeshes
Wenn ein EditableMesh aus einem bestehenden Mesh-Asset erstellt wird (via AssetService:CreateEditableMeshAsync() ), wird das daraus resultierende bearbeitbare Mesh standardmäßig mit einer festen Größe fixiert.Fixierte Netze sind in Bezug auf Speicher effizienter, aber Sie können nicht die Anzahl von Vektoren, Gesichtern oder Attributen ändern.Nur die Werte der vertex-Attribute und Positionen können bearbeitet werden.
local AssetService = game:GetService("AssetService")
-- Erstellen von bearbeitbarem Netz ohne feste Größe Standard
local editableMeshFromAsset = nil
local success, errorMessage = pcall(function()
editableMeshFromAsset = AssetService:CreateEditableMeshAsync(Content.fromAssetId(ASSET_ID), {FixedSize = false})
end)
Stabile Vexel/Gesicht-IDs
Viele EditableMesh -Methoden nehmen vertex , normal , UV , Farbe und Gesicht IDs.Diese werden als Ganzzahlen in Luau dargestellt, aber sie erfordern eine spezielle Handhabung.Der Hauptunterschied besteht darin, dass IDs stabil sind und sie gleich bleiben, auch wenn sich andere Teile des Meshes ändern.Wenn zum Beispiel ein EditableMesh fünf Verteile hat {1, 2, 3, 4, 5} und Sie den Verteiler 4 entfernen, werden die neuen Verteile {1, 2, 3, 5} sein.
Beachten Sie, dass die IDs nicht garantiert in Ordnung sind und es möglicherweise Lücken in der Nummerierung gibt, so dass Sie beim Durchlaufen von Knoten oder Gesichtern durch die Tabelle, die von GetVertices() oder GetFaces() zurückgegeben wird, durchlaufen sollten.
Vertex-Attributte aufteilen
Ein Vertex ist ein Eck eines Gesichts und verbindet Gesichter topologisch miteinander.Vertices können mehrere Attribute haben: Position, Normal, UV-Koordinate, Farbe und Transparenz.
Manchmal ist es für alle Gesichter, die einen Vektor berühren, nützlich, die gleichen Attributswerte zu verwenden, aber manchmal möchten Sie, dass verschiedene Gesichter verschiedene Attributswerte auf demselben Vektor verwenden.Zum Beispiel auf einer glatten Kugel wird jeder Vektor nur eine einzige Norm haben.Im Gegensatz dazu wird an der Ecke eines Würfels der Vektor 3 verschiedene Normale haben (eins für jedes angrenzende Gesicht).Du kannst auch Nähte in den UV-Koordinaten oder scharfe Änderungen in den Vektorfarben haben.
Wenn Gesichter erstellt werden, wird jederVertex standardmäßig eines jedes Attributes haben: ein normales, eine UV-Koordinate und eine Farbe/Transparenz.Wenn du eine Naht erstellen möchtest, solltest du neue Attribute erstellen und sie auf dem Gesicht setzen.Zum Beispiel erstellt dieser Code einen scharfen Würfel:
local AssetService = game:GetService("AssetService")
-- Angesichts von 4 Gipfel-IDs fügt es ein neues Normal und 2 Dreieck hinzu, um einen scharfen Quad zu bilden
local function addSharpQuad(editableMesh, vid0, vid1, vid2, vid3)
local nid = editableMesh:AddNormal() -- Dies erstellt eine normale ID, die automatisch berechnet wird
local fid1 = editableMesh:AddTriangle(vid0, vid1, vid2)
editableMesh:SetFaceNormals(fid1, {nid, nid, nid})
local fid2 = editableMesh:AddTriangle(vid0, vid2, vid3)
editableMesh:SetFaceNormals(fid2, {nid, nid, nid})
end
-- Erstellt einen Würfel mit abgeflachten Kanten zwischen den 6 Seiten
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) -- Vordere
addSharpQuad(editableMesh, v1, v3, v4, v2) -- Zurück
addSharpQuad(editableMesh, v1, v5, v7, v3) -- Linker
addSharpQuad(editableMesh, v2, v4, v8, v6) -- Rechts
addSharpQuad(editableMesh, v1, v2, v6, v5) -- Unten
addSharpQuad(editableMesh, v3, v7, v8, v4) -- Oben
editableMesh:RemoveUnused()
return editableMesh
end
Wickeln
Mesh-Gesichter haben eine Vorderseite und eine Rückseite.Wenn Meshes gezeichnet werden, werden nur die Vorderseiten der Gesichter standardmäßig gezeichnet, obwohl Sie dies ändern können, indem Sie die Eigenschaft des Meshes auf festlegen.
Die Reihenfolge der Vertikale um das Gesicht bestimmt, ob du auf die Vorderseite oder die Rückseite schaust.Die Vorderseite des Gesichts ist sichtbar, wenn die Gipfel im Uhrzeigersinn um sie herum gehen.

FACS-Positionen
Animierbare Köpfe verwenden das Facial Action Coding System (FACS).Siehe die FACS-Posenreferenz für hilfreiche Informationen bei der Verwendung von GetFacsPoses() und ähnlichen Methoden.
Jede FACS-Position wird durch einen Enum.FacsActionUnit Wert angegeben.Für die FACS-Pose können virtuelle Knochen jedes ein CFrame haben, das die ursprünglichen Knochen CFrame in der Bind-Pose des Meshes in die CFrame für die Pose der FACS-Aktionseinheit umwandelt.Alle Knochen CFrames sind im lokalen Raum des Meshes.
Diese FACS-Posen werden während der Animation zusammen gemischt.Manchmal produziert das Mischen der Basisposen schlechte Ergebnisse.In diesen Fällen kannst du die Mischung bestimmter Kombinationen von Grundstellungen mit einer korrigierenden Korrekturpose, die angenehmer ist, überschreiben.Eine korrigierende Pose wird durch 2 oder 3 Enum.FacsActionUnit Werte angegeben.Wie eine Basis-FACS-Pose, für eine korrigierende Pose können virtuelle Knochen jedes ein CFrame haben, das die ursprüngliche CFrame der Knochen in der Bind-Pose des Netzes in die CFrame für diese FACS-Korrektur verwandelt.
Beschränkungen
EditableMesh hat derzeit ein Limit von 60.000 Kanten und 20.000 Dreieck. Wenn du zu viele Kanten oder Dreieck hinzufügst, wird ein Fehler auftreten.
Zusammenfassung
Eigenschaften
Gibt true zurück, wenn ein Mesh eine feste Größe hat.
Methoden
Fügt einer Geometrie eine neue Farbe hinzu und gibt eine stabile Farb-ID zurück.
Fügt ein neues Normal zur Geometrie hinzu und gibt eine stabile normale ID zurück.
Fügt einem Netz ein neues Dreieck hinzu und gibt eine stabile Gesichts-ID zurück.
Fügt eine neue UV zur Geometrie hinzu und gibt eine stabile UV-ID zurück.
Fügt einen neuen Vektor zur Geometrie hinzu und gibt eine stabile Vektor-ID zurück.
Zerstört das Netz.
Findet den nächsten Punkt auf der Oberfläche des Meshes.
Findet den nächstenVertex zu einem bestimmten Punkt im Raum.
Findet alle Vektoren innerhalb einer bestimmten Sphäre.
Gibt eine Liste von Gesichtern zurück, die sich neben einem bestimmten Gesicht befinden.
Gibt eine Liste von Kanten zurück, die zu einem bestimmten Knoten adjekt sind.
Gibt die Farbe für die angegebene Farb-ID zurück.
Gibt die Farbe alpha (Transparenz) bei der angegebenen Farb-ID zurück.
Gibt alle Farben des Meshes zurück.
Gibt die Farb-IDs des Gesichts für die Kanten auf dem Gesicht zurück.
Gibt die normalen IDs des Gesichts für die Kanten auf dem Gesicht zurück.
Gibt die UV-IDs des Gesichts für die Kanten auf dem Gesicht zurück.
Gibt die vertex-IDs des Gesichts zurück.
Gibt alle Gesichter des Meshes zurück.
Gibt den normalen Vektor für die angegebene normale ID zurück.
Gibt alle Normals des Meshes zurück.
Holt die Position eines Verts.
Gibt UV-Koordinaten bei der angegebenen UV-ID zurück.
Gibt alle UVs des Meshes zurück.
Gibt alle Kanten als Liste stabiler Kanten-IDs zurück.
Gibt eine Zeichenkette zurück, die eine stabile ID beschreibt, nützlich für Fehlerbehebungszwecke.
Verschmilzt Kanten, die sich berühren.
Entfernt ein Gesicht mit seiner stabilen Gesichts-ID.
Entfernt alle unbenutzten vertexe, normale, uvs und farben und gibt die entfernten ids zurück.
Setze diese normale ID zurück, um sie automatisch berechnet zu werden.
Legt die Farbe für eine Farb-ID fest.
Legt die Farbe alpha (Transparenz) für eine Farb-ID fest.
Setzt die Gipfelfarben des Gesichts auf neue Farb-IDs.
Setzt die Normalvektoren des Gesichts auf neue normale IDs.
Setzt die UV-Vektoren des Gesichts auf neue UV-IDs.
Setzt die Gipfel des Gesichts auf neue Gipfel-IDs.
Setze das Normale für eine normale ID.
Setzt eineVertex-Position im lokalen Objektbereich des Meshes.
Legt UV-Koordinaten für eine UV-ID fest.
Teilt alle Gesichter auf dem Netz in Dreieckform auf.
Eigenschaften
FixedSize
Methoden
AddTriangle
Parameter
Rückgaben
Destroy
Rückgaben
FindVerticesWithinSphere
Parameter
Rückgaben
RaycastLocal
Parameter
Rückgaben
Code-Beispiele
local AssetService = game:GetService("AssetService")
local Workspace = game:GetService("Workspace")
-- Initialize EditableMesh in space
local editableMesh = nil
local success, errorMsg = pcall(function()
editableMesh = AssetService:CreateEditableMeshAsync(Content.fromUri("rbxassetid://ASSET_ID"))
end)
local meshPart = nil
if success and editableMesh then
meshPart = AssetService:CreateMeshPartAsync(
Content.fromObject(editableMesh),
{ CollisionFidelity = Enum.CollisionFidelity.Hull }
)
meshPart.Parent = Workspace
else
warn(errorMsg)
end
-- Function that will cast a ray from the given point, returning the world point of the hit and the UV coordinate
local function castRayFromCamera(meshPart: MeshPart, editableMesh: EditableMesh, viewportPoint: Vector3)
if not meshPart then
return
end
-- Calculate how much the object is being scaled in each dimension
local renderScale = meshPart.Size / meshPart.MeshSize
-- Create ray from camera along the direction of a clicked point
local ray = Workspace.CurrentCamera:ViewportPointToRay(viewportPoint.X, viewportPoint.Y)
-- Convert to object space to use with RaycastLocal()
local relativeOrigin = meshPart.CFrame:PointToObjectSpace(ray.Origin) / renderScale
local relativeTarget = meshPart.CFrame:PointToObjectSpace(ray.Origin + ray.Direction * 100) / renderScale
local relativeDirection = relativeTarget - relativeOrigin
local faceId, point, barycentricCoordinate, vertId1, vertId2, vertId3 =
editableMesh:RaycastLocal(relativeOrigin, relativeDirection)
if not faceId then
-- Didn't hit any faces
return
end
-- Compute the hit point in world space
local worldHitPoint = meshPart.CFrame:PointToWorldSpace(point * renderScale)
-- Get the UVs on the face
local uvId1 = editableMesh:GetVertexFaceUV(vertId1, faceId)
local uvId2 = editableMesh:GetVertexFaceUV(vertId2, faceId)
local uvId3 = editableMesh:GetVertexFaceUV(vertId3, faceId)
local uv1 = editableMesh:GetUV(uvId1)
local uv2 = editableMesh:GetUV(uvId2)
local uv3 = editableMesh:GetUV(uvId3)
-- Interpolate UVs within the face based on the barycentric coordinate
local u = (barycentricCoordinate.x * uv1.x) + (barycentricCoordinate.y * uv2.x) + (barycentricCoordinate.z * uv3.x)
local v = (barycentricCoordinate.x * uv1.y) + (barycentricCoordinate.y * uv2.y) + (barycentricCoordinate.z * uv3.y)
return worldHitPoint, Vector2.new(u, v)
end