Gerçek zamanlı olarak oyuncuların avatar bedenleri oluşturup, özelleştirmesine ve satın almasına olanak tanıyan bir deneyim yayınlayabilirsiniz. Satın alındıklarında, bu özel bedeller doğrudan oyuncunun Roblox envanterine kaydedilir ve oyuncuların diğer deneyimlerde özelleştirilmiş avatarları giymelerine olanak tanır.
Deneyim sahipleri, deneyim içerisinde avatar oluşturma uyguladıklarında, hem avatar nesnesinin yaratıcısı hem de deneyim sahibi olarak Marketplace komisyonlarından faydalanırlar. Deneyim içerisinde oluşturulan bir varlık incelendiğinde, nesne oluşturulduğu deneyime bir bağlantı sağlar.
Deneyim içerisinde oluşturma işlemini Roblox'un Avatar Oluşturucu demosunda test edebilirsiniz.
Deneyim İçerisinde Oluşturmayı Uygulama
İlk deneyim içi avatar oluşturma projenizi oluşturmak için aşağıdaki talimatları ve kod referanslarını kullanın. Aşağıdaki talimatlar, oyuncuların değiştirebileceği ve özelleştirebileceği temel bir beden Model kullanır.
Başlamadan önce, aşağıdakilerle tanışın:
- Avatar modelleri — Aşağıdaki uygulama, Roblox'un 15 parça spesifikasyonlarını karşılayan bir temel bedenin ithal edilmesini gerektirir. Bu Model, ek kullanıcı özelleştirmeleri ve değişiklikler için bir temel olarak hizmet eder.
- Temel beden, Roblox'un Avatar beden yönergeleri ile ilgili gereksinimleri karşılamalıdır; bu, yüz rigging'i için gereken minimum FACS kontrol sayısını içerir.
- Avatar oluşturma token'ları — Avatar oluşturmayı uygulayan deneyimlerin en az bir oluşturma token'ı gereklidir. Bu token'lar, Robux ile satın alınır ve deneyim içerisinde yapılan alımlar için fiyat ve diğer satış ayarlarını belirlemenize olanak tanır.
- API sınıfları
- AvatarCreationService — Avatar oluşturma istemlerini ve doğrulamaları yönetir.
- EditableImage — Doku oluşturma ve manipulasyonu işlemlerini yönetir.
- EditableMesh — Mesh geometrisinin runtime manipulasyonunu yönetir.
- WrapDeformer — Avatar karakterlerinin 3D kıyafet giymesini sağlayan görünmez dış kafes geometrisinin runtime manipulasyonunu yönetir.
Temel Beden İçe Aktarma
Temel beden, kullanıcıların özelleştirip düzenleyebileceği ilk yapıyı oluşturur. Kendi Model'ınızı kullanabilir veya Importer ile özel bir varlık ithal edebilir ve Avatar Kurulumu aracılığıyla yapılandırabilirsiniz.
Temel bedenler, Roblox'un avatar spesifikasyonlarına uymalı ve kafa, gövde, sol kol, sol bacak, sağ kol ve sağ bacak gibi 6 beden parçasını oluşturan 15 MeshPart instance'ı gibi bileşenleri içermelidir; ayrıca diğer avatar bileşenleri de gereklidir.
Doğru yapılandırılmış avatar bedenlerine dair referanslar ve örnekler için Avatar referansları sayfasına bakın.
Düzenleme API'lerini Uygulama
Kullanıcıların deneyiminizde bir avatar üzerindeki MeshPart instance'larını düzenleyebileceği bir sistem geliştirmek için EditableImage ile doku düzenlemesi yapın, EditableMesh ile mesh düzenlemesi yapın ve WrapDeformer'ı mesh düzenlemeleri sırasında skin ve FACS verilerini korumak için kullanın.
Temel bedeninizi ithal ettikten sonra, EditableImages, EditableMeshes ve WrapDeformers'yi ayarlamak için aşağıdaki betiği kullanın.
local AssetService = game:GetService("AssetService")local function setupBodyPart(meshPart, wrapTarget)-- MeshPart'a WrapDeformer oluştur ve eklelocal wrapDeformer = Instance.new("WrapDeformer")wrapDeformer.Parent = meshPart-- Kafesinin mesh'i için bir editable mesh oluşturlocal cageEditableMesh: EditableMesh =AssetService:CreateEditableMeshAsync(Content.fromUri(wrapTarget.CageMeshId), {FixedSize = true,})-- Kafesinin mesh'ine WrapDeformer'i atayınwrapDeformer:SetCageMeshContent(Content.fromObject(cageEditableMesh))endlocal function setupRigidMesh(meshPart)-- Orijinal MeshPart'tan bir editable mesh oluşturlocal editableMesh = AssetService:CreateEditableMeshAsync(Content.fromUri(meshPart.MeshId), {FixedSize = true,})-- Editable mesh'ten yeni bir MeshPart oluşturlocal newMeshPart = AssetService:CreateMeshPartAsync(Content.fromObject(editableMesh))-- Boyut, konum ve doku özelliklerini orijinal MeshPart'tan kopyalayınnewMeshPart.Size = meshPart.SizenewMeshPart.CFrame = meshPart.CFramenewMeshPart.TextureContent = meshPart.TextureContent-- Yeni MeshPart'ı orijinal MeshPart'a uygulayınmeshPart:ApplyMesh(newMeshPart)endlocal function setupMeshTexture(meshPart, textureIdToEditableImageMap)-- Eğer bu TextureID için EditableImage zaten varsa, yenisini oluşturmaktansa onu kullanif textureIdToEditableImageMap[meshPart.TextureID] thenmeshPart.TextureContent =Content.fromObject(textureIdToEditableImageMap[meshPart.TextureID])returnend-- Yeni bir EditableImage oluştur ve doku içeriği olarak uygulalocal editableImage = AssetService:CreateEditableImageAsync(Content.fromUri(meshPart.TextureID))textureIdToEditableImageMap[meshPart.TextureID] = editableImagemeshPart.TextureContent = Content.fromObject(editableImage)endlocal function setupModel(model)-- Doku ID'sine göre EditableImage instance'larını yeniden kullanma haritasılocal textureIdToEditableImageMap = {}for _, descendant in model:GetDescendants() doif not descendant:IsA("MeshPart") thencontinueend-- MeshPart'ı WrapTarget varlığına göre yapılandırın-- WrapTarget mevcutsa, bir EditableMesh ile WrapDeformer çocuk ekleyin-- Aksi takdirde, EditableMesh'i doğrudan MeshPart'a uygulayınlocal wrapTarget = descendant:FindFirstChildOfClass("WrapTarget")if wrapTarget thensetupBodyPart(descendant, wrapTarget)elsesetupRigidMesh(descendant)end-- MeshPart için EditableImage'i yapılandırınsetupMeshTexture(descendant, textureIdToEditableImageMap)endendOyuncuların temel bedeniniz üzerinde yeniden renk vermesine, çizim yapmasına veya çıkartma eklemesine olanak tanıyan EditableImage araçları oluşturun. DrawImage(), DrawRectangle(), WritePixelsBuffer() gibi API'lerden yararlanabilirsiniz.
Gelişmiş dönüşümler için, DrawImageTransformed() bir EditableImage'i diğerine çizerken konum, döndürme ve ölçek belirtmenize olanak tanır. Benzer şekilde, DrawImageProjected() ise, EditableImage örneği bir MeshPart ile kullanıldığında düzgün bir şekilde çizilen resmi projekte eder.
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 = (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 ve EditableMesh kullanarak bedeninizdeki mesh deformasyonlarını düzenlemeye yönelik araçlar oluşturun.
WrapDeformer, render edilmiş MeshPart geometrisinin canlı deformasyonlarını yönetirken altta yatan skinning ve FACS verilerini korur.
EditableMesh, WrapDeformer'ın yanıt verdiği kafes mesh'ini düzenlemenizi sağlar.
- WrapDeformer:SetCageMeshContent() ile WrapDeformer'a ilgili kafes mesh'ini temsil eden EditableMesh örneğini uygulayın.
- EditableMesh, örneğin SetPosition() kullanarak, vertex'leri deforme etmek ve MeshPart'ın şeklini düzenlemek için kullanılır.
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
Oluşturma İstemini Oluşturma
Temel bedeninizi ve düzenleme API'lerinizi ayarladıktan sonra, kullanıcıların deneyimden oluşturup satın alması için bir istem yaratın. Bunu, AvatarCreationService:PromptCreateAvatarAsync() kullanarak gerçekleştirin.
export type BodyPartInfo = {
bodyPart: Enum.BodyPart,
instance: Instance -- Oluşturulan MeshParts ile birlikte klasör
}
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("Başarıyla yüklendi. BundleId: ", bundleIdOrErrorMessage)
print("Başarıyla yüklendi. OutfitId: ", outfitId)
else
print("Hatalı yükleme. Hata mesajı:", bundleIdOrErrorMessage)
end
else
print("Avatar oluşturma başarısız")
end
end
AvatarCreationService:PromptCreateAvatarAsync() fonksiyonu, satın alınmak veya oluşturulmak istenen avatarı temsil etmek için bir HumanoidDescription parametresi alır. Avatar oluşturma için karakterin HumanoidDescription'u 6 beden parçası için oluşturulacak yeni varlıkları içermelidir
(Baş,
Gövde,
SağBacak,
SolBacak,
SağKol,
SolKol). İsteğe bağlı olarak, yeni bir Saç aksesuarı da dahil edilebilir.
Bunu desteklemek için HumanoidDescription, 6 BodyPartDescription çocuğu içermelidir. Her BodyPartDescription.Instance özellikleri, beden parçasını oluşturan tüm MeshPart instance'larını içeren bir Folder'a işaret etmelidir. Örneğin, SolKol klasörü, SolEldiven, SolÜstKol ve SolAltKol MeshParts içerir. Ayrıca BodyPartDescription.BodyPart özelliği de ilgili Enum.BodyPart'a ayarlanmalıdır.
Her 15 MeshPart beden parçası şunları içermelidir:
- Bir EditableImage.
- Bir WrapDeformer ve içinde bir EditableMesh.
Verilen HumanoidDescription, oluşturma esnasında beden parçalarını veya aksesuarları temsil etmek için herhangi bir mevcut varlık ID'si içermemelidir. Öte yandan, HumanoidDescription, BodyTypeScale,
BaşScale,
YükseklikScale,
GenişlikScale, ve
OrantıScale'in humanoid ölçeklerini içerebilir. Dikkat edilmesi gereken, bir temel bedenin ithal edildiği ölçeklerin, HumanoidDescription'a sağlanan ölçekler ile eşleşmesidir.

Aksesuarları Dahil Etme
Bir aksesuar (örneğin saç) ekleyecekseniz, HumanoidDescription'ın bir AccessoryDescription çocuğu içermesi gerekir. Bu durumda:
- AccessoryDescription.Instance özelliği, Accessory instance'ına işaret eder.
- AccessoryDescription.AccessoryType özelliği, ilgili Enum.AccessoryType'a ayarlanmalıdır.
- Enum.AccessoryType.Hair kullanıyorsanız, MeshPart'ın bir EditableImage içermesi gerekir. Ancak, bir WrapDeformer çocuğu içermemeli, fakat EditableMesh doğrudan MeshPart üzerinde tanımlanmalıdır.
Avatar Oluşturma Token'ı Oluşturma
AvatarCreationService:PromptCreateAvatarAsync() Avatar Oluşturma Token ID'si parametresini alır. Bu token, evreninizden oluşturulanlar için anahtardır ve deneyiminizden avatar oluşturma fiyatını ayarlamak için kullanacağınız şeydir. Token oluşturma ile ilgili talimatlar ve ek ayrıntılar için Avatar Oluşturma Token'ları sayfasını inceleyin.
Token'ınızı satın aldıktan ve oluşturduktan sonra, AvatarCreationService:PromptCreateAvatarAsync() API'si için kullanabileceğiniz ID'yi bulmak üzere Creator Hub'da token'ı inceleyebilirsiniz.

Oyunlara Katılan Oyuncuları Atıflar İle Yanıtlama
Deneyim içerisinde oluşturulan avatar paketleri, avatarın oluşturulduğu orijinal deneyime bir atıf bağlantısı içerir. Avatar başka bir oyuncu tarafından incelendiğinde, avatarın oluşturulduğu deneyimi ziyaret etme seçeneği sunan bir istem görüntülenir.

Bu atıf bağlantısını kullanarak deneyiminize katılan oyuncuları işlemek için Player:GetJoinData() kullanın ve döndürülen tabloyu GameJoinContext için ayıklayın.
GameJoinContext, aşağıdaki tablo değerlerini içerir:
- JoinSource — Enum.JoinSource
- Bu atıf bağlantısından deneyiminize katılan bir Player, oluşturulmuş bir nesneden giriş yapıldığını belirtmek için Enum.JoinSource.CreatedItemAttribution değeri alır.
- ItemType — isteğe bağlı Enum.AvatarItemType
- AssetId — isteğe bağlı string
- OutfitId — isteğe bağlı string
- AssetType — isteğe bağlı Enum.AssetType