Makyaj için deneyim içi 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.

Deneyiminiz, oyuncuların gerçek zamanlı olarak makyaj varlıkları oluşturmasına, özelleştirmesine ve satın almasına olanak tanımanın yanı sıra deneyim içi avatar vücut oluşturma işlevselliğini de sunar. Satın alındığında, makyaj varlıkları doğrudan oyuncunun Roblox envanterine kaydedilir.

Deneyim sahipleri, deneyim içi makyaj oluşturma uyguladıklarında, makyaj varlığının yayımcısı olarak Pazar komisyonlarından faydalanırken, onu oluşturan oyuncu varlığın yaratıcısıdır.

Deneyim içi makyaj oluşturmayı nasıl uygulayabilirsiniz

Oyuncuları avatarlarının başında makyaj varlıklarını boyamaya, birleştirmeye ve satın almaya yönlendirmek için aşağıdaki talimatları ve kod referanslarını kullanın.

Başlamadan önce, aşağıdakilerle tanışın:

  • Avatar oluşturma jetonları — Makyaj oluşturma uygulayan deneyimlerin, oluşturma türü oluşturmak istediğiniz makyaj varlık türüyle eşleşen en az bir oluşturma jetonuna ihtiyacı vardır.
  • API sınıfları
    • AvatarCreationService — Avatar varlık oluşturma istemlerini ve doğrulamayı yönetir.
    • EditableImage — Dokuları çalışma zamanında oluşturma ve manipüle etme işlemlerini yönetir.
    • EditableMesh — Mesh geometrisini çalışma zamanında manipüle eder.
    • WrapDeformer — Avatar karakterlerinin 3D kıyafet ve aksesuarları takmasına olanak tanıyan görünmez dış kafes geometrisini çalışma zamanında manipüle eder; katmanlı kaş ve kirpik mesh'leri de dahil.
    • WrapTarget — Bir kafes mesh'i ile bir hedef mesh arasındaki bağlamayı temsil eder ve ikisi arasında doku alanı dönüşümünü açığa çıkarır.
    • WrapTextureTransfer — Bir makyaj çıkartması da dahil olmak üzere, bir ana mesh etrafında sarılmayı kolaylaştırır.

Tek varlık veya çoklu varlık akışını seçin

Makyaj oluşturma, bir makyaj varlığı oluşturup oluşturmadığınıza bağlı olarak iki istemi destekler veya birkaç katmanı bir kıyafet içinde birleştirir:

PromptCreateMakeupAsync() bir dizi makyaj varlık girişi alır; her giriş şunları içerir:

  • O katman için bir oluşturma jeton ID'si.
  • Varlığı oluşturmak için kullanılacak örnek.
  • Katmanın AvatarAssetType'ı olarak bir Enum.AvatarAssetType.
  • Birden fazla katman üst üste geldiğinde birleştirmeyi kontrol eden bir sıralama düzeni.

Bir bütün olarak kıyafet için Enum.PromptCreateMakeupResult döndürür (Success, PartialSuccess, CreationFailure, PermissionDenied, Timeout, NoUserInput, veya UnknownFailure), ayrıca genel sonuç PartialSuccess olduğunda hangi bireysel katmanların başarılı olduğunu belirlemenizi sağlayan bir varlık sonucu döndürür.

Bir avatar oluşturma jetonu oluşturun

Her makyaj varlık türü, PromptCreateAvatarAssetAsync()'ye geçirdiğiniz Enum.AvatarAssetType ile eşleşen veya PromptCreateMakeupAsync() kullanırken her katmanın varlık türü ile eşleşen kendi avatar oluşturma jetonuna ihtiyaç duyar. Gerekli jetonları, gönderim girişlerini oluşturmadan önce oluşturun ve ardından her jeton ID'sini sunucu tarafı istemi için kopyalayın.

Göz Makyajı olarak ayarlanmış Seçim Jetonu türü açılır menüsü, bir jetonun bağlam menüsü açık ve Kopyala Jeton ID'si seçeneği gösteriliyor

Aşağıdaki adımlar, oyuncunun başında projeksiyon boyama işlemini ana yol olarak kullanır. Bunun yerine bir yazar başı veya başka bir deneyim sahibi mesh'i kendi yerel UV alanında boyuyorsanız, Bir dokuyu kafes alanı ve hedef alanı arasında taşıma bölümünü takip edin, ardından Çıkartmayı oluşturun ve oluşturma için gönderin bölümünde ana yola yeniden katılın.

Oyuncunun başında bir makyaj dokusu boyayın

Yeni bir varlık üzerinde boyama yapmanın aksine, genellikle yerel oyuncunun başından doğrudan EditableMesh okuyamazsınız — baş mesh'i, diğer oyuncu sahipliğindeki örnekler gibi aynı izin modeline tabidir. Tek istisna, deneyimin baş mesh'ine sahip olduğunda (örneğin, deneyim sahibi bir NPC veya deneyimin kendisinin oluşturduğu bir vücut); bu durumda EditableMesh'i doğrudan kullanabilirsiniz, avatar vücut oluşturma için yaptığınız gibi. Aksi takdirde, bir WrapTextureTransfer hazırlayın ve çizim yaparken projeksiyon hedefi olarak kullanın:

  1. Oyuncunun başı için projeksiyon mesh verilerini hazırlamak ve önbelleğe almak için WrapTextureTransfer:PrepareProjectionMeshDataAsync() çağrısını yapın. Bu, o transfer üzerinde herhangi bir projeksiyon çizim veya örnekleme çağrısı yapmadan önce tamamlanmalıdır. Temel baş mesh'i değişirse, boyamaya devam etmeden önce WrapTextureTransfer'i yeniden hazırlayın.
  2. Hazırlanan WrapTextureTransfer'i DrawImageProjected() veya SampleImageProjected()'ye projeksiyon kaynağı olarak geçin. Bu yöntemler, oyuncunun gerçek baş şekli üzerinde doğrudan boyama yapmanıza olanak tanıyan bir WrapTextureTransfer'i EditableMesh'e alternatif olarak kabul eder.
local AssetService = game:GetService("AssetService")
-- Oyuncunun başı için daha önce oluşturduğunuz bir WrapTextureTransfer'i geçin.
local function paintMakeupLayer(textureTransfer: WrapTextureTransfer, brushConfig, projectionParams)
local success, err = pcall(function()
textureTransfer:PrepareProjectionMeshDataAsync()
end)
if not success then
warn("Projeksiyon mesh verilerini hazırlamakta başarısız:", err)
return
end
local makeupTexture = AssetService:CreateEditableImage()
if not makeupTexture then
warn("Makyaj dokusu oluşturmak için yeterli düzenlenebilir bellek yok")
return
end
makeupTexture:DrawImageProjected(textureTransfer, projectionParams, brushConfig)
return makeupTexture
end

Bir dokuyu kafes alanı ve hedef alanı arasında taşıyın

Bir oyuncuya ait baş üzerinde, Oyuncunun başında bir makyaj dokusu boyayın bölümünde açıklandığı gibi, hazırlanan bir WrapTextureTransfer aracılığıyla doğrudan boyama yapmak, baş mesh'inin hedef UV alanında başlamaz — projeksiyon yolu, her zaman paylaşılan kafes UV düzeninde çalışır, bu nedenle sonuç zaten gönderim için hazır bir kafes alanı dokusudur.

Kafes/hedef dönüşümü, doğrudan kendi yerel hedef UV alanında boyayabileceğiniz bir yazar başı veya deneyim sahibi bir mesh ile çalışırken önemlidir:

Yeniden kullanılabilir bir kafes alanı makyaj dokusunu o mesh'in hedef alanına düzenleme için CreateTextureInTargetSpaceAsync() kullanın, ardından düzenlenmiş sonucu kafes alanına geri dönüştürmek için CreateTextureInCageSpaceAsync() kullanın ve makyaj varlığı olarak gönderin.

Makyaj için, kafes alanı dönüşümünü tüm kafes yerine makyaj bölgesi ile sınırlayın. AvatarCreationService:GetValidationRules() çağrısını yapın ve MakeupRules.WrapTextureTransferUVBounds'ı okuyun; bu, MinBound ve MaxBound değerlerini Vector2 olarak sağlar. Bunları CreateTextureInCageSpaceAsync()'ye MinUVBounds ve MaxUVBounds olarak geçin. Bu seçenekler olmadan, yöntem sınırları tüm kafesten türetir, makyaj bölgesini kullanmaz. Her sınır sonlu olmalıdır ve maksimum, her iki eksende de minimumdan büyük olmalıdır.

local AvatarCreationService = game:GetService("AvatarCreationService")
local validationRules = AvatarCreationService:GetValidationRules()
local makeupBounds = validationRules.MakeupRules.WrapTextureTransferUVBounds
local cageSpaceTexture = wrapTarget:CreateTextureInCageSpaceAsync(targetSpaceTexture, {
MinUVBounds = makeupBounds.MinBound,
MaxUVBounds = makeupBounds.MaxBound,
})

Çıkartmayı oluşturun ve oluşturma için gönderin

Yüz, dudak ve göz makyajı boyanmış dokulardır, kaşlar ve kirpikler ise diğer 3D kıyafet ve aksesuarlar gibi bireysel olarak oluşturulmuş katmanlı mesh aksesuarlarıdır. Her katmanın gönderim girişini buna göre oluşturun:

Elde edilen örneği, Bir avatar oluşturma jetonu oluşturun bölümünden alınan eşleşen jeton ID'si, varlık türü ve katman sırası ile birleştirin. Aşağıdaki örnek, bu girişleri alır ve otomatik olarak doğru API'yi seçer: Tek bir giriş için AvatarCreationService:PromptCreateAvatarAssetAsync(), veya iki veya daha fazla katmanı bir kıyafet içinde birleştirirken AvatarCreationService:PromptCreateMakeupAsync().

Her iki istem de varlığı oluşturma ve denetim için göndermeden önce oyuncuya son bir onay ekranı gösterir.

local AssetService = game:GetService("AssetService")
local AvatarCreationService = game:GetService("AvatarCreationService")
type MakeupEntry = {
tokenId: string,
instance: Instance,
assetType: Enum.AvatarAssetType,
sortOrder: number,
}
-- Yüz, dudak ve göz makyajı: tamamlanmış dokuyu bir Çıkartma içine sarın ve
-- Boyamak için kullanılan WrapTextureTransfer'i, Çıkartma'nın tek çocuğu olarak ekleyin.
local function createMakeupTextureEntry(
tokenId: string,
texture: EditableImage,
textureTransfer: WrapTextureTransfer,
assetType: Enum.AvatarAssetType,
sortOrder: number
): MakeupEntry
local decal = AssetService:CreateDecalAsync({
TextureContent = Content.fromObject(texture),
})
decal.Face = Enum.NormalId.Front
textureTransfer.Parent = decal
return {
tokenId = tokenId,
instance = decal,
assetType = assetType,
sortOrder = sortOrder,
}
end
-- Kaşlar ve kirpikler: doğrudan oluşturulmuş katmanlı mesh Aksesuarını geçin.
local function createMakeupAccessoryEntry(
tokenId: string,
accessory: Accessory,
assetType: Enum.AvatarAssetType,
sortOrder: number
): MakeupEntry
return {
tokenId = tokenId,
instance = accessory,
assetType = assetType,
sortOrder = sortOrder,
}
end
local function submitMakeupEntries(entries: {MakeupEntry}, player: Player, headColor: Color3?)
local assetEntries = {}
for _, entry in entries do
table.insert(assetEntries, {
TokenId = entry.tokenId,
Instance = entry.instance,
AvatarAssetType = entry.assetType,
SortOrder = entry.sortOrder,
})
end
if #assetEntries == 1 then
local entry = assetEntries[1]
local success, result, assetIdOrErrorMessage = pcall(function()
return AvatarCreationService:PromptCreateAvatarAssetAsync(
entry.TokenId,
player,
entry.Instance,
entry.AvatarAssetType
)
end)
if success and result == Enum.PromptCreateAssetResult.Success then
print("Başarıyla Yüklenmiş AssetId:", assetIdOrErrorMessage)
else
print("Makyaj varlığı oluşturma başarısız:", assetIdOrErrorMessage)
end
else
local success, result, perAssetResults = pcall(function()
return AvatarCreationService:PromptCreateMakeupAsync(player, assetEntries, headColor)
end)
if success and result == Enum.PromptCreateMakeupResult.Success then
print("Makyaj kıyafeti başarıyla oluşturuldu")
else
print("Makyaj kıyafeti oluşturma sonucu:", result, perAssetResults)
end
end
end

Denetimi yönetin

Bir makyaj varlığı oluşturulduktan sonra, deneyim içinde kullanılmadan önce denetimden geçer.

  • AvatarAssetModerationCompleted olayını dinleyerek, PromptCreateAvatarAssetAsync() ile oluşturulan bireysel makyaj varlığının denetim sürecinin ne zaman tamamlandığını öğrenin.
  • PromptCreateMakeupAsync() ile oluşturulan çok katmanlı bir kıyafet için, AvatarAssetModerationCompleted hala kıyafetteki her bireysel makyaj varlığı için bir kez tetiklenir ve ayrıca AvatarOutfitModerationCompleted olayı, kıyafet için bir kez tetiklenir. Her ikisini de dinleyin: belirli bir katmanın denetim sonucunu bilmeniz gerekiyorsa varlık düzeyindeki olayı kullanın ve tüm görünümün deneyim içinde kullanılabilir olduğunu bilmek için kıyafet düzeyindeki olayı kullanın.
©2026 Roblox Corporation. Roblox, the Roblox logo and Powering Imagination are among our registered and unregistered trademarks in the U.S. and other countries.