Create {itemType}
Gelir elde etme
Policies and Guidelines

Deneyim İçerisinde Avatar Oluşturma

*Bu içerik, yapay zekâ (beta) kullanılarak çevrildi ve hatalar içerebilir. Sayfayı İngilizce görüntülemek için buraya tıkla.

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.

  1. 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 ekle
    local wrapDeformer = Instance.new("WrapDeformer")
    wrapDeformer.Parent = meshPart
    -- Kafesinin mesh'i için bir editable mesh oluştur
    local cageEditableMesh: EditableMesh =
    AssetService:CreateEditableMeshAsync(Content.fromUri(wrapTarget.CageMeshId), {
    FixedSize = true,
    })
    -- Kafesinin mesh'ine WrapDeformer'i atayın
    wrapDeformer:SetCageMeshContent(Content.fromObject(cageEditableMesh))
    end
    local function setupRigidMesh(meshPart)
    -- Orijinal MeshPart'tan bir editable mesh oluştur
    local editableMesh = AssetService:CreateEditableMeshAsync(Content.fromUri(meshPart.MeshId), {
    FixedSize = true,
    })
    -- Editable mesh'ten yeni bir MeshPart oluştur
    local newMeshPart = AssetService:CreateMeshPartAsync(Content.fromObject(editableMesh))
    -- Boyut, konum ve doku özelliklerini orijinal MeshPart'tan kopyalayın
    newMeshPart.Size = meshPart.Size
    newMeshPart.CFrame = meshPart.CFrame
    newMeshPart.TextureContent = meshPart.TextureContent
    -- Yeni MeshPart'ı orijinal MeshPart'a uygulayın
    meshPart:ApplyMesh(newMeshPart)
    end
    local function setupMeshTexture(meshPart, textureIdToEditableImageMap)
    -- Eğer bu TextureID için EditableImage zaten varsa, yenisini oluşturmaktansa onu kullan
    if textureIdToEditableImageMap[meshPart.TextureID] then
    meshPart.TextureContent =
    Content.fromObject(textureIdToEditableImageMap[meshPart.TextureID])
    return
    end
    -- Yeni bir EditableImage oluştur ve doku içeriği olarak uygula
    local editableImage = AssetService:CreateEditableImageAsync(Content.fromUri(meshPart.TextureID))
    textureIdToEditableImageMap[meshPart.TextureID] = editableImage
    meshPart.TextureContent = Content.fromObject(editableImage)
    end
    local function setupModel(model)
    -- Doku ID'sine göre EditableImage instance'larını yeniden kullanma haritası
    local textureIdToEditableImageMap = {}
    for _, descendant in model:GetDescendants() do
    if not descendant:IsA("MeshPart") then
    continue
    end
    -- 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ın
    local wrapTarget = descendant:FindFirstChildOfClass("WrapTarget")
    if wrapTarget then
    setupBodyPart(descendant, wrapTarget)
    else
    setupRigidMesh(descendant)
    end
    -- MeshPart için EditableImage'i yapılandırın
    setupMeshTexture(descendant, textureIdToEditableImageMap)
    end
    end
  2. Oyuncuları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
      )
      end
      local 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)
      end
      local 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).Unit
      local 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
  3. WrapDeformer ve EditableMesh kullanarak bedeninizdeki mesh deformasyonlarını düzenlemeye yönelik araçlar oluşturun.

    1. WrapDeformer, render edilmiş MeshPart geometrisinin canlı deformasyonlarını yönetirken altta yatan skinning ve FACS verilerini korur.

    2. EditableMesh, WrapDeformer'ın yanıt verdiği kafes mesh'ini düzenlemenizi sağlar.

      1. WrapDeformer:SetCageMeshContent() ile WrapDeformer'a ilgili kafes mesh'ini temsil eden EditableMesh örneğini uygulayın.
      2. 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.CageMeshId
      local wrapDeformer = Instance.new("WrapDeformer")
      wrapDeformer.Parent = meshPart
      local cageEditableMesh = AssetService:CreateEditableMeshAsync(cageMeshId)
      local verticesWithinSphere =
      cageEditableMesh:FindVerticesWithinSphere(controlPointCenter, controlPointRadius)
      for _, vertexId in verticesWithinSphere do
      local vertexPosition = cageEditableMesh:GetPosition(vertexId)
      cageEditableMesh:SetPosition(vertexId, vertexPosition + controlPointDeformation)
      end
      wrapDeformer: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:

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:

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:

©2026 Roblox Corporation. Roblox, the Roblox logo and Powering Imagination are among our registered and unregistered trademarks in the U.S. and other countries.