EditableMesh

Tampilkan yang Tidak Digunakan Lagi

*Konten ini diterjemahkan menggunakan AI (Beta) dan mungkin mengandung kesalahan. Untuk melihat halaman ini dalam bahasa Inggris, klik di sini.

Tidak Dapat Dibuat

EditableMesh mengubah meshes visual yang diterapkan saat terhubung ke MeshPart , memungkinkan pencarian dan modifikasi meshes baik di Studio maupun di pengalaman.

Mengaktifkan untuk Pengalaman Terpublikasi

Untuk tujuan keamanan, menggunakan EditableMesh gagal secara default untuk pengalaman yang dipublikasikan.Untuk mengaktifkan penggunaan, Anda harus berusia 13+ dan ID diverifikasi.Setelah Anda diverifikasi, buka Pengaturan Permainan Studio, pilih Keamanan , dan aktifkan toggle Izinkan API Mesh/Gambar .

Izin

Untuk mencegah penyalahgunaan, AssetService:CreateEditableMeshAsync() hanya akan memungkinkan Anda untuk memuat dan mengedit aset mesh:

  • Yang dimiliki oleh pencipta pengalaman (jika pengalaman dimiliki oleh individu).
  • Yang dimiliki oleh kelompok (jika pengalaman dimiliki oleh kelompok).
  • Yang dimiliki oleh pengguna Studio yang masuk (jika file tempat belum disimpan atau dipublikasikan ke Roblox).

Batas-batas Memori

Aset yang dapat diedit saat ini mahal untuk penggunaan memori.Untuk mengurangi dampaknya terhadap kinerja klien, EditableMesh memiliki anggaran memori klien yang ketat, meskipun server, Studio, dan plugin beroperasi dengan memori tak terbatas.Menggunakan FixedSize mungkin membantu Anda tetap berada dalam anggaran memori dan, dalam beberapa skenario, menghubungkan satu EditableMesh ke banyak MeshParts (multireferensi) dapat membantu dengan optimisasi memori.

Pembuatan dan Tampilan

Sebuah EditableMesh dapat dibuat dari sebuah Content yang ada dari MeshPart atau ID mesh menggunakan AssetService:CreateEditableMeshAsync() , atau kosong EditableMesh dapat dibuat dengan AssetService:CreateEditableMesh() .Kemudian dapat ditampilkan, dimodifikasi, dan model tabrakannya diperbarui.Tidak semua langkah diperlukan; misalnya, Anda mungkin ingin membuat EditableMesh hanya untuk raycast tanpa pernah menampilkannya.


local AssetService = game:GetService("AssetService")
-- Buat EditableMesh kosong
local editableMesh = AssetService:CreateEditableMesh()
-- Buat EditableMesh dari ID aset
local editableMeshFromAsset = nil
local success, errorMessage = pcall(function()
editableMeshFromAsset = AssetService:CreateEditableMeshAsync(Content.fromAssetId(ASSET_ID))
end)
-- Buat EditableMesh dari EditableMesh lain
local editableMeshFromAnother = nil
local success, errorMessage = pcall(function()
editableMeshFromAnother = AssetService:CreateEditableMeshAsync(Content.fromObject(OTHER_EDITABLE_MESH))
end)
-- Buat EditableMesh dari MeshPart
local editableMeshFromMeshPart = nil
local success, errorMessage = pcall(function()
editableMeshFromMeshPart = AssetService:CreateEditableMeshAsync(MESH_PART.MeshContent)
end)

Sebuah EditableMesh ditampilkan saat terhubung ke MeshPart baru, melalui AssetService:CreateMeshPartAsync() .Anda dapat membuat lebih banyak instansi yang merujuk pada yang sama , atau tautkan ke yang ada melalui .


local AssetService = game:GetService("AssetService")
local Workspace = game:GetService("Workspace")
-- Buat EditableMesh dari ID aset
local editableMeshFromAsset = nil
local success, errorMessage = pcall(function()
editableMeshFromAsset = AssetService:CreateEditableMeshAsync(Content.fromAssetId(ASSET_ID))
end)
-- Buat MeshPart baru yang terhubung ke EditableMesh
local newMeshPart = nil
local success, errorMessage = pcall(function()
newMeshPart = AssetService:CreateMeshPartAsync(Content.fromObject(editableMeshFromAsset))
end)
-- Alternatifnya, hubungkan MeshPart baru yang dibuat di atas ke MeshPart yang ada
local existingMeshPart = Workspace:FindFirstChild("EXISTING_MESH_PART")
existingMeshPart:ApplyMesh(newMeshPart)

Untuk menghitung ulang kolisi dan geometri cairan setelah diedit, Anda dapat sekali lagi memanggil AssetService:CreateMeshPartAsync() dan MeshPart:ApplyMesh() untuk memperbarui MeshPart yang ada.Umumnya disarankan untuk melakukan ini pada akhir edit konsep, bukan setelah panggilan individu ke metode yang memanipulasi geometri.Perubahan visual pada mesh akan selalu segera dicerminkan oleh mesin, tanpa perlu memanggil AssetService:CreateMeshPartAsync() .

Mesh Ukuran Tetap

Saat membuat EditableMesh dari aset mesh yang ada (melalui AssetService:CreateEditableMeshAsync() ), mesh yang dihasilkan memiliki ukuran tetap secara default.Meshes ukuran tetap lebih efisien dalam hal memori tetapi Anda tidak dapat mengubah jumlah vertiks, wajah, atau atribut.Hanya nilai atribut vertex dan posisi yang dapat diedit.


local AssetService = game:GetService("AssetService")
-- Buat EditableMesh tanpa default ukuran tetap
local editableMeshFromAsset = nil
local success, errorMessage = pcall(function()
editableMeshFromAsset = AssetService:CreateEditableMeshAsync(Content.fromAssetId(ASSET_ID), {FixedSize = false})
end)

ID Vertex/Wajah Stabil

Banyak metode EditableMesh banyak mengambil vertex , normal , UV , warna dan wajah ID.Ini diwakili sebagai bilangan bulat di Luau tetapi mereka membutuhkan penanganan khusus.Perbedaan utama adalah bahwa ID tetap stabil dan tetap sama bahkan jika bagian lain dari mesh berubah.Sebagai contoh, jika sebuah EditableMesh memiliki lima vertiks {1, 2, 3, 4, 5} dan Anda menghapus vertiks 4 , vertiks baru akan menjadi {1, 2, 3, 5} .

Perhatikan bahwa ID tidak dijamin berada dalam urutan dan mungkin ada lubang dalam penomoran, jadi saat mengulang melalui vertex atau wajah, Anda harus mengulang melalui tabel yang dikembalikan oleh GetVertices() atau GetFaces() .

Atribut Vertex Terbagi

Sebuah vertex adalah sudut wajah, dan terhubung secara topologis wajah bersama-sama.Vertiks dapat memiliki beberapa atribut: posisi, normal, koordinat UV, warna, dan transparansi.

Terkadang berguna untuk semua wajah yang menyentuh vertex untuk menggunakan nilai atribut yang sama, tetapi terkadang Anda akan ingin wajah yang berbeda menggunakan nilai atribut yang berbeda di vertex yang sama.Sebagai contoh, pada bola mulus, setiap vertex hanya akan memiliki satu normal.Sebaliknya, di sudut kubus, vertex akan memiliki 3 normal yang berbeda (satu untuk setiap wajah berdekatan).Anda juga dapat memiliki celah di koordinat UV atau perubahan tajam pada warna vertex.

Saat membuat wajah, setiap vertex akan secara default memiliki satu dari setiap atribut: satu normal, satu koordinat UV, dan satu warna/transparansi.Jika Anda ingin membuat celah, Anda harus membuat atribut baru dan menetapkannya di wajah.Sebagai contoh, kode ini akan membuat kubus tajam:


local AssetService = game:GetService("AssetService")
-- Dengan diberikan 4 ID sudut, menambahkan normal baru dan 2 segi tiga, membuat quad tajam
local function addSharpQuad(editableMesh, vid0, vid1, vid2, vid3)
local nid = editableMesh:AddNormal() -- Ini membuat ID normal yang dihitung secara otomatis
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
-- Membuat kubus dengan tepi yang meningkat di antara 6 sisi
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) -- Depan
addSharpQuad(editableMesh, v1, v3, v4, v2) -- Kembali
addSharpQuad(editableMesh, v1, v5, v7, v3) -- Terpisah
addSharpQuad(editableMesh, v2, v4, v8, v6) -- Tepat
addSharpQuad(editableMesh, v1, v2, v6, v5) -- Bawah
addSharpQuad(editableMesh, v3, v7, v8, v4) -- Atas
editableMesh:RemoveUnused()
return editableMesh
end

Memutar

Wajah mesh memiliki sisi depan dan sisi belakang.Saat menarik meshes, hanya bagian depan wajah yang ditarik secara default, meskipun Anda dapat mengubah ini dengan mengatur properti meshes' DoubleSided ke true.

Pesanan vertiks di sekitar wajah menentukan apakah Anda melihat ke depan atau ke belakang.Bagian depan wajah terlihat saat vertex berjalan searah jam terbalik di sekitarnya.

Order of the vertices around the face

Posisi FACS

Kepala yang dapat dianimasikan menggunakan Sistem Koding Aksi Wajah (FACS).Lihat referensi posisi FACS untuk informasi berguna saat menggunakan GetFacsPoses() dan metode serupa.

Setiap posisi FACS diberi kode oleh nilai Enum.FacsActionUnit .Untuk posisi FACS, tulang virtual masing-masing dapat memiliki CFrame yang mengubah tulang awal CFrame dalam posisi ikatan jaring ke posisi CFrame untuk unit aksi FACS itu.Semua tulang CFrames berada di ruang lokal mesh.

Posisi FACS ini dicampur bersama selama animasi.Terkadang, pencampuran posisi dasar menghasilkan hasil buruk.Dalam kasus tersebut, Anda dapat menggantikan pencampuran kombinasi spesifik posisi dasar dengan posisi korektif yang lebih menyenangkan.Posisi korektif ditentukan oleh 2 atau 3 nilai Enum.FacsActionUnit .Seperti posisi FACS dasar, untuk posisi korektif, tulang virtual masing-masing dapat memiliki CFrame yang mengubah CFrame awal tulang dalam posisi bind mesh ke CFrame untuk FACS korektif itu.

Keterbatasan

EditableMesh saat ini memiliki batas 60.000 vertex dan 20.000 segi tiga. Mencoba menambahkan terlalu banyak vertex atau segi tiga akan menyebabkan kesalahan.

Rangkuman

Properti

  • Hanya Baca
    Tidak Direplikasi
    Keamanan Roblox
    Baca Paralel

    Kembalikan true jika mesh adalah ukuran tetap.

Metode

Properti

FixedSize

Hanya Baca
Tidak Direplikasi
Keamanan Roblox
Baca Paralel

Metode

AddColor

Parameter

color: Color3
Nilai Default: ""
alpha: number
Nilai Default: ""

Memberikan nilai

AddNormal

Parameter

normal: Vector3
Nilai Default: ""

Memberikan nilai

AddTriangle

Parameter

vertexId0: number
Nilai Default: ""
vertexId1: number
Nilai Default: ""
vertexId2: number
Nilai Default: ""

Memberikan nilai

AddUV

Parameter

Nilai Default: ""

Memberikan nilai

AddVertex

Parameter

Nilai Default: ""

Memberikan nilai

Destroy

()

Memberikan nilai

()

FindClosestPointOnSurface

Parameter

point: Vector3
Nilai Default: ""

Memberikan nilai

FindClosestVertex

Parameter

toThisPoint: Vector3
Nilai Default: ""

Memberikan nilai

FindVerticesWithinSphere

Parameter

center: Vector3
Nilai Default: ""
radius: number
Nilai Default: ""

Memberikan nilai

GetAdjacentFaces

Parameter

faceId: number
Nilai Default: ""

Memberikan nilai

GetAdjacentVertices

Parameter

vertexId: number
Nilai Default: ""

Memberikan nilai

GetCenter


Memberikan nilai

GetColor

Parameter

colorId: number
Nilai Default: ""

Memberikan nilai

GetColorAlpha

Parameter

colorId: number
Nilai Default: ""

Memberikan nilai

GetColors


Memberikan nilai

GetFaceColors

Parameter

faceId: number
Nilai Default: ""

Memberikan nilai

GetFaceNormals

Parameter

faceId: number
Nilai Default: ""

Memberikan nilai

GetFaceUVs

Parameter

faceId: number
Nilai Default: ""

Memberikan nilai

GetFaceVertices

Parameter

faceId: number
Nilai Default: ""

Memberikan nilai

GetFaces


Memberikan nilai

GetNormal

Parameter

normalId: number
Nilai Default: ""

Memberikan nilai

GetNormals


Memberikan nilai

GetPosition

Parameter

vertexId: number
Nilai Default: ""

Memberikan nilai

GetSize


Memberikan nilai

GetUV

Parameter

uvId: number
Nilai Default: ""

Memberikan nilai

GetUVs


Memberikan nilai

GetVertices


Memberikan nilai

IdDebugString

Parameter

id: number
Nilai Default: ""

Memberikan nilai

MergeVertices

Map

Parameter

mergeTolerance: number
Nilai Default: ""

Memberikan nilai

Map

RaycastLocal

Parameter

origin: Vector3
Nilai Default: ""
direction: Vector3
Nilai Default: ""

Memberikan nilai

Contoh Kode

EditableMesh:RaycastLocal()

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

RemoveFace

()

Parameter

faceId: number
Nilai Default: ""

Memberikan nilai

()

RemoveUnused


Memberikan nilai

ResetNormal

()

Parameter

normalId: number
Nilai Default: ""

Memberikan nilai

()

SetColor

()

Parameter

colorId: number
Nilai Default: ""
color: Color3
Nilai Default: ""

Memberikan nilai

()

SetColorAlpha

()

Parameter

colorId: number
Nilai Default: ""
alpha: number
Nilai Default: ""

Memberikan nilai

()

SetFaceColors

()

Parameter

faceId: number
Nilai Default: ""
ids: Array
Nilai Default: ""

Memberikan nilai

()

SetFaceNormals

()

Parameter

faceId: number
Nilai Default: ""
ids: Array
Nilai Default: ""

Memberikan nilai

()

SetFaceUVs

()

Parameter

faceId: number
Nilai Default: ""
ids: Array
Nilai Default: ""

Memberikan nilai

()

SetFaceVertices

()

Parameter

faceId: number
Nilai Default: ""
ids: Array
Nilai Default: ""

Memberikan nilai

()

SetNormal

()

Parameter

normalId: number
Nilai Default: ""
normal: Vector3
Nilai Default: ""

Memberikan nilai

()

SetPosition

()

Parameter

vertexId: number
Nilai Default: ""
Nilai Default: ""

Memberikan nilai

()

SetUV

()

Parameter

uvId: number
Nilai Default: ""
Nilai Default: ""

Memberikan nilai

()

Triangulate

()

Memberikan nilai

()

Acara