คุณสามารถเผยแพร่ประสบการณ์ที่ช่วยให้ผู้เล่นสามารถสร้าง ปรับแต่ง และซื้อร่างกายอวาตาร์ได้ในเวลาจริงเมื่อซื้อแล้ว ร่างกายที่กำหนดเองเหล่านี้จะบันทึกโดยตรงในคลังสินค้า Roblox ของผู้เล่น ทำให้ผู้เล่นสามารถติดตั้งและสวมใส่อวตารที่กำหนดเองในประสบการณ์อื่นได้
เจ้าของประสบการณ์ที่ใช้การสร้างอวตารในประสบการณ์ได้รับประโยชน์จาก ค่าธรรมเนียมตลาด ทั้งในฐานะผู้สร้างอวตารและเจ้าของประสบการณ์หากสินทรัพย์ที่สร้างในประสบการณ์ถูกตรวจสอบ รายการจะให้ลิงก์ไปยังประสบการณ์เดิมที่สร้างขึ้น
คุณสามารถทดสอบการสร้างในประสบการณ์ในการสาธิตของ Roblox's Avatar Creator
การสร้างสรรค์
ใช้คำแนะนำและรหัสอ้างอิงต่อไปนี้เพื่อสร้างโครงการสร้างอวาตาร์ประสบการณ์แรกของคุณคำแนะนำต่อไปนี้ใช้ร่างกายหลัก Model ที่ผู้เล่นสามารถแก้ไขและปรับแต่งก่อนเผยแพร่
ก่อนที่จะเริ่มต้น กำลังติดตาม:
- รูปแบบตัวละคร — การดำเนินการต่อไปต้องนำเข้าร่างกายพื้นฐานที่ตรงกับข้อกำหนดส่วน 15 ของ Robloxนี้ Model ให้บริการเป็นฐานสำหรับการปรับแต่งและการแก้ไขผู้ใช้เพิ่มเติม
- ร่างกายฐานต้องปฏิบัติตามคำแนะนำด้านร่างกายของ Roblox Avatar body guidelines รวมถึงจํานวน FACS ขั้นต่ําสําหรับการปรับแต่งใบหน้า
- โทเค็นการสร้างอวตาร — ประสบการณ์ที่ใช้สร้างอวตารต้องมีโทเค็นการสร้างอย่างน้อยหนึ่งโทเค็นโทเค็นเหล่านี้ต้องใช้ Robux ในการซื้อและอนุญาตให้คุณตั้งราคาและการตั้งค่าการขายอื่นๆ สำหรับการซื้อที่ทำในประสบการณ์
- คลาส API
- AvatarCreationService — จัดการการสร้างอวตารที่ระบุและยืนยันการตรวจสอบ
- EditableImage — จัดการการสร้างและการปรับแต่งเทกเจอร์ในระหว่างการทำงาน
- EditableMesh — จัดการการปรับแต่งระหว่างการทำงานของเมทริกซ์ภูมิทัศน์
- WrapDeformer — จัดการการปรับแต่งเวลาของภาชนะที่มองไม่เห็นที่ช่วยให้ตัวละครอวาตาร์สามารถสวมใส่เสื้อผ้า 3D ได้ 3D
นำเข้าร่างกายฐาน
ร่างกายหลักทำหน้าที่เป็นพื้นฐานเริ่มต้นที่ผู้ใช้สามารถปรับแต่งและแก้ไขได้คุณสามารถใช้ของคุณเอง Model หรือนำเข้าสินทรัพย์ที่กําหนดเองด้วย ผู้นําเข้า 3D และติดตั้งผ่าน การตั้งค่าอวาตาร์
ร่างกายฐานต้องปฏิบัติตามข้อกำหนดของอวตารของ Roblox และต้องรวมส่วนประกอบเช่น 15 ตัวอย่างที่ประกอบขึ้นเป็น 6 ส่วนของร่างกาย: หัว, ลําตัว, แขนซ้าย, ขาซ้าย, แขนขวา, และขาขวา รวมถึงส่วนประกอบอวตารอื่น ๆ อีกด้วย
สำหรับการอ้างอิงและตัวอย่างของร่างกายอวาตาร์ที่กำหนดค่าอย่างถูกต้อง ดู การอ้างอิงอวาตาร์
ใช้งาน API การแก้ไข
เพื่อพัฒนาระบบที่ผู้ใช้สามารถแก้ไขตัวอย่าง MeshPart การสร้างสรรค์ใช้ EditableImage สำหรับการแก้ไขเทกเจอร์ EditableMesh สำหรับการแก้ไขเมช และ WrapDeformer สำหรับการรักษาข้อมูลผิวหนังและ FACS ในระหว่างการแก้ไขเมช
หลังจากนำเข้าร่างกายหลักแล้วใช้สคริปต์ต่อไปนี้เพื่อตั้งค่า EditableImages , EditableMeshes และ WrapDeformers ของคุณ
local AssetService = game:GetService("AssetService")local function setupBodyPart(meshPart, wrapTarget)-- สร้างและแนบ WrapDeformer ไปยัง MeshPartlocal wrapDeformer = Instance.new("WrapDeformer")wrapDeformer.Parent = meshPart-- สร้างเมชที่แก้ไขได้สำหรับเมชของกรงเป้าหมายห่อlocal cageEditableMesh: EditableMesh =AssetService:CreateEditableMeshAsync(Content.fromUri(wrapTarget.CageMeshId), {FixedSize = true,})-- กำหนดเมทช์กรงให้กับ WrapDeformerwrapDeformer:SetCageMeshContent(Content.fromObject(cageEditableMesh))endlocal function setupRigidMesh(meshPart)-- สร้างเมชที่แก้ไขได้จาก MeshPart เดิมlocal editableMesh = AssetService:CreateEditableMeshAsync(Content.fromUri(meshPart.MeshId), {FixedSize = true,})-- สร้าง MeshPart ใหม่จากเมชที่แก้ไขได้local newMeshPart = AssetService:CreateMeshPartAsync(Content.fromObject(editableMesh))-- คัดลอกขนาด ตําแหน่ง และเทกเจอร์จาก MeshPart เดิมnewMeshPart.Size = meshPart.SizenewMeshPart.CFrame = meshPart.CFramenewMeshPart.TextureContent = meshPart.TextureContent-- นำ MeshPart ใหม่กลับไปที่ต้นฉบับmeshPart:ApplyMesh(newMeshPart)endlocal function setupMeshTexture(meshPart, textureIdToEditableImageMap)-- หาก EditableImage มีอยู่แล้วสำหรับ TextureID นี้ให้ใช้ซ้ำแทนที่จะสร้างใหม่if textureIdToEditableImageMap[meshPart.TextureID] thenmeshPart.TextureContent =Content.fromObject(textureIdToEditableImageMap[meshPart.TextureID])returnend-- สร้างภาพที่แก้ไขได้ใหม่และใช้เป็นเนื้อหาของเทกเจอร์local editableImage = AssetService:CreateEditableImageAsync(Content.fromUri(meshPart.TextureID))textureIdToEditableImageMap[meshPart.TextureID] = editableImagemeshPart.TextureContent = Content.fromObject(editableImage)endlocal function setupModel(model)-- แผนที่สำหรับการใช้ซ้ำตัวอย่าง EditableImage โดยรหัสเทกเจอร์local textureIdToEditableImageMap = {}for _, descendant in model:GetDescendants() doif not descendant:IsA("MeshPart") thencontinueend-- กำหนดค่า MeshPart ตามการปรากฏตัวของ WrapTarget-- หาก WrapTarget ปรากฏขึ้น เพิ่มลูก WrapDeformer ด้วย EditableMesh-- มิฉะนั้นใช้ EditableMesh กับ MeshPart โดยตรงlocal wrapTarget = descendant:FindFirstChildOfClass("WrapTarget")if wrapTarget thensetupBodyPart(descendant, wrapTarget)elsesetupRigidMesh(descendant)end-- กำหนดค่าภาพที่แก้ไขได้สำหรับชิ้นส่วน MeshsetupMeshTexture(descendant, textureIdToEditableImageMap)endendสร้างเครื่องมือ EditableImage ที่ช่วยให้ผู้เล่นสามารถเปลี่ยนสี วาด หรือเพิ่มสติกเกอร์ลงบนร่างกายหลักของคุณคุณสามารถใช้ประโยชน์จาก API ในเช่น DrawImage() , DrawRectangle() , WritePixelsBuffer() .
สำหรับการเปลี่ยนแปลงขั้นสูง DrawImageTransformed() ช่วยให้คุณสามารถระบุตำแหน่ง การหมุน และขนาดเมื่อวาดภาพที่แก้ไขได้หนึ่งภาพไปยังอีกภาพหนึ่งเช่นเดียวกัน DrawImageProjected() ทำงานคล้ายกับ DrawImage() แต่โครงการภาพวาดที่วาดได้อย่างถูกต้องหากตัวอย่าง EditableImage ถูกใช้ด้วย MeshPart
local function recolorTexture(meshPart: MeshPart,color: Color3)local bodyPartTexture = AssetService:CreateEditableImageAsync(meshPart.TextureID)meshPart.TextureContent = Content.fromObject(bodyPartTexture)bodyPartTexture:DrawRectangle(Vector2.new(0, 0),bodyPartTexture.Size,color,0,Enum.ImageCombineType.Overwrite)endlocal function applySticker(meshPart: MeshPart,textureCoordinate: Vector2,stickerId: TextureId)local bodyPartTexture = AssetService:CreateEditableImageAsync(meshPart.TextureID)meshPart.TextureContent = Content.fromObject(bodyPartTexture)local stickerTexture = AssetService:CreateEditableImageAsync(stickerId)bodyPartTexture:DrawImage(textureCoordinate, stickerTexture, Enum.ImageCombineType.BlendSourceOver)endlocal function applyStickerProjected(meshPart: MeshPart,targetMesh: EditableMesh,stickerId: TextureId,raycastHitPos: Vector3)local bodyPartTexture = AssetService:CreateEditableImageAsync(meshPart.TextureID)local relativePos = meshPart.CFrame:PointToWorldSpace(raycastHitPos)local direction = (game.Workspace.CurrentCamera.CFrame.Position - relativePos).Unitlocal projectionParams: ProjectionParams = {Direction = meshPart.CFrame:VectorToObjectSpace(direction),Position = meshPart.CFrame:PointToObjectSpace(relativePos),Size = Vector3.new(1, 1, 1),Up = meshPart.CFrame:VectorToObjectSpace(Vector3.new(0, 1, 0)),}local stickerTexture = AssetService:CreateEditableImageAsync(stickerId)local localBrushConfig: BrushConfig = {Decal = stickerTexture,ColorBlendType = Enum.ImageCombineType.BlendSourceOver,AlphaBlendType = Enum.ImageAlphaType.Default,BlendIntensity = 1,FadeAngle = 90.0}bodyPartTexture:DrawImageProjected(targetMesh, projectionParams, localBrushConfig)end
โดยใช้ WrapDeformer และ EditableMesh สร้างเครื่องมือสำหรับแก้ไขการเปลี่ยนรูปเมชในร่างกายของคุณ
WrapDeformer จัดการการเปลี่ยนรูปแบบสดของรูปทรงที่เรนเดอร์ได้รับ MeshPart ในขณะที่รักษาข้อมูลสกินและข้อมูล FACS พื้นฐานไว้
EditableMesh ช่วยให้คุณสามารถปรับแต่งตาข่ายกรงที่ WrapDeformer ตอบสนองได้
- ใช้ WrapDeformer:SetCageMeshContent() เพื่อใช้ตัวอย่าง EditableMesh ที่แทนที่ตาข่ายกรงที่เกี่ยวข้องกับ WrapDeformer
local function deformBodyPart(meshPart: MeshPart,controlPointCenter: Vector3,controlPointRadius: number,controlPointDeformation: Vector3)local wrapTarget = meshPart:FindFirstChildWhichIsA("WrapTarget")local cageMeshId = wrapTarget.CageMeshIdlocal wrapDeformer = Instance.new("WrapDeformer")wrapDeformer.Parent = meshPartlocal cageEditableMesh = AssetService:CreateEditableMeshAsync(cageMeshId)local verticesWithinSphere =cageEditableMesh:FindVerticesWithinSphere(controlPointCenter, controlPointRadius)for _, vertexId in verticesWithinSphere dolocal vertexPosition = cageEditableMesh:GetPosition(vertexId)cageEditableMesh:SetPosition(vertexId, vertexPosition + controlPointDeformation)endwrapDeformer:SetCageMeshContent(Content.fromObject(cageEditableMesh))end
สร้างคําขอสร้าง
หลังจากตั้งค่าร่างกายหลักและแก้ไข API แล้ว สร้างคำเตือนสำหรับผู้ใช้เพื่อสร้างและซื้อจากประสบการณ์โดยใช้ AvatarCreationService:PromptCreateAvatarAsync()
export type BodyPartInfo = {
bodyPart: Enum.BodyPart,
instance: Instance --โฟลเดอร์ที่มีชิ้นส่วนเมชที่สร้างขึ้น
}
export type BodyPartList = {BodyPartInfo}
local function publishAvatar(bodyPartInstances: BodyPartList, player: Player, tokenId: string)
local humanoidDescription = Instance.new("HumanoidDescription")
for _, bodyPartInfo in bodyPartInstances do
local bodyPartDescription = Instance.new("BodyPartDescription")
bodyPartDescription.Instance = bodyPartInfo.instance
bodyPartDescription.BodyPart = bodyPartInfo.bodyPart
bodyPartDescription.Parent = humanoidDescription
end
local success, result, bundleIdOrErrorMessage, outfitId = pcall(function()
return AvatarCreationService:PromptCreateAvatarAsync(tokenId, player, humanoidDescription)
end)
if success then
if result == Enum.PromptCreateAvatarResult.Success then
print("Successfully uploaded with BundleId: ", bundleIdOrErrorMessage)
print("Successfully uploaded with OutfitId: ", outfitId)
else
print("Unsuccessfully uploaded with error message:", bundleIdOrErrorMessage)
end
else
print("Avatar creation unsuccessful")
end
end
AvatarCreationService:PromptCreateAvatarAsync() ใช้พารามิเตอร์ HumanoidDescription การสร้างสรรค์HumanoidDescription จะต้องรวมทรัพยากรใหม่ที่จะสร้างสำหรับแต่ละส่วนของร่างกาย 6 ส่วน ( Head , Torso , RightLeg , LeftLeg , RightArm , LeftArm )ไอเท็มเสริมHair ได้
เพื่อสนับสนุนสิ่งนี้ HumanoidDescription ควรรวมเด็ก 6 BodyPartDescription คนแต่ละคุณสมบัติ BodyPartDescription.Instance อ้างอิงถึง Folder ซึ่งรวมถึงทุกตัวอย่าง MeshPart ที่ทำให้เกิดส่วนของร่างกายตัวอย่างเช่น โฟลเดอร์ LeftArm มี LeftHand , LeftUpperArm และ LeftLowerArm``Class.MeshPart|MeshPartsคุณสมบัติ BodyPartDescription.BodyPart ควรตั้งเป็น Enum.BodyPart ที่เกี่ยวข้องด้วย
แต่ละส่วนของร่างกาย 15 MeshPart ต้องรวมถึง:
- An EditableImage .
- A WrapDeformer ที่มี EditableMesh .
รหัสสินทรัพย์ที่ให้มา HumanoidDescription ไม่ควรรวมรหัสสินทรัพย์ที่มีอยู่แล้วล่วงหน้าเพื่อแทนที่ส่วนหรืออุปกรณ์เสริมในการสร้างที่ตั้งใจไว้ในทางกลับกัน HumanoidDescription อาจรวมถึงเครื่องชั่งมนุษย์ของ BodyTypeScale , HeadScale , HeightScale , WidthScale และ ProportionScaleโปรดใส่ใจกับเครื่องชั่งที่ร่างฐานถูกนำมาใช้เพื่อให้ตรงกับเครื่องชั่งที่ให้ไว้กับ HumanoidDescription

รวมอุปกรณ์เสริม
หากรวมอุปกรณ์เสริม เช่น ผม ตัว HumanoidDescription ควรรวมเด็ก AccessoryDescription โดยมี:
- คุณสมบัติ AccessoryDescription.Instance อ้างถึงตัวอย่าง Accessory
- คุณสมบัติ AccessoryDescription.AccessoryType ถูกตั้งค่าเป็น Enum.AccessoryType ที่เกี่ยวข้อง
- ในกรณีที่รวม Enum.AccessoryType.Hair ในการสร้างของคุณ ตัว MeshPart ควรรวม EditableImageอย่างไรก็ตาม ไม่ควรรวมเด็ก WrapDeformer แต่ควรรวมชุด EditableMesh โดยตรงบน MeshPart
สร้างโทเค็นการสร้างอวตาร
AvatarCreationService:PromptCreateAvatarAsync() ใช้พารามิเตอร์ ID การสร้างอวตาร โทเค็นนี้เป็นกุญแจสําคัญสําหรับการสร้างจากจักรวาลของคุณและเป็นสิ่งที่คุณสามารถใช้เพื่อตั้งราคาการสร้างอวาตาร์จากประสบการณ์ของคุณสำหรับคําแนะนําและรายละเอียดเพิ่มเติมเกี่ยวกับการสร้างโทเค็นดูที่ โทเค็นการสร้างอวตาร
หลังจากซื้อและสร้างโทเค็นแล้ว คุณสามารถตรวจสอบโทเค็นใน Creator Hub เพื่อค้นหารหัสที่คุณสามารถใช้สำหรับ API AvatarCreationService:PromptCreateAvatarAsync() ได้

ตอบสนองต่อผู้เล่นที่เข้าร่วมโดยการโยนความคิดเห็น
แพ็คเกจตัวละครที่สร้างขึ้นในประสบการณ์รวมถึงลิงก์การอ้างอิงไปยังประสบการณ์เดิมที่ตัวละครถูกสร้างขึ้นหากอวตารถูกตรวจสอบโดยผู้เล่นคนอื่น จะมีการแสดงคำเตือนพร้อมตัวเลือกในการเยี่ยมชมประสบการณ์ที่อวตารถูกสร้างขึ้น

เพื่อจัดการผู้เล่นที่เข้าร่วมประสบการณ์ของคุณโดยใช้ลิงก์การโยบายนี้, ใช้ Player:GetJoinData() และแยกตารางที่ส่งคืนสำหรับ GameJoinContext
GameJoinContext รวมถึงมูลค่าตารางต่อไปนี้:
- JoinSource — Enum.JoinSource
- การเชื่อมโยงประสบการณ์ของคุณจากลิงก์การจัดสรรนี้จะมี เพื่อระบุการเข้าถึงจากไอเทมที่สร้างขึ้น
- ItemType — ตัวเลือก Enum.AvatarItemType
- AssetId — ตัวเลือก string
- OutfitId — ตัวเลือก string
- AssetType — ตัวเลือก Enum.AssetType