Paketler paketi

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

Paketler özelliği paketi, oyunculara indirimde öğe koleksiyonlarını satmak için kutudan çıkma işlevselliği sunar.Oyuncuların deneyim içi para veya Robux kullanarak paket satın almasına izin vermek istediğinizi ve hangi paket türünü kullanmak istediğinizi, ne satmak istediğiniz öğeleri ve oyuncuları oynanışsırasında nasıl uyaracağınızı seçebilirsiniz.

Paketin özelleştirme seçeneklerini kullanarak, paketlerinizi deneyimlerinizin tasarım ve monetize hedeflerine uyacak şekilde özelleştirebilirsiniz, örneğin:

  • Yeni oyunculara değer sağlayan ve erken harcama teşvik eden indirimli başlangıç paketleri sunarak düşük bir dönüşüm oranı hedeflemek
  • Bir dizi oyuncuya hitap etmek için çeşitli fiyat noktalarında öğeleri birleştirerek harcama derinliğini artırmak.
  • Canlı operasyonların (CanlıOps) canlı etkinliklerini sınırlı süreli özel eşyalardan oluşan paketlerle monetize etmek.

Paket alın

Yaratıcı Dükkanı Roblox ve Roblox topluluğu tarafından yapılan tüm varlıkları bulmak için kullanabileceğiniz Araç Çubuğu'nun bir sekmesidir, model, görüntü, mesh, ses, eklenti, video ve font varlıkları dahil olmak üzere projelerinizde kullanılan tüm varlıkları bulmak için.Özellik paketleri de dahil olmak üzere açık bir deneyime bir veya daha fazla varlık doğrudan eklemek için Yaratıcı Dükkanı kullanabilirsiniz!

Her özellik paketi doğru çalışması için Çekirdek özellik paketine ihtiyaç duyar. Çekirdek ve Paketler özellik paketlerinin envanterinizde olduğunda, platformdaki herhangi bir projede yeniden kullanabilirsiniz.

Paketleri envanterinden deneyiminize almak için:

  1. Studio'daki envanterinize Çekirdek ve Paketler özelliği paketini eklemek için aşağıdaki bileşenlerden Envantere Ekle bağlantısına tıklayın.

  2. Araç çubuğunda, Görüntüle sekmesini seçin.

  3. Araç çantasına tıklayın . Araç çantası penceresi görüntülenir.

    Studio's View tab with the Toolbox tool highlighted.
  4. Araç kutusu penceresinde, Envanter sekmesine tıklayın. Modellerim sıralaması görüntülenir.

    Studio's Toolbox window with the Inventory tab highlighted.
  5. Özellik Paketi Çekirdeği tuşuna tıklayın, ardından Paket Özellik Paketi tuşuna tıklayın.Her iki paket klasörü Gezgini penceresinde görüntülenir.

  6. Paket klasörlerini Yeniden Yansıtılan Depoya sürükle.

  7. Veri depolama çağrılarını paketlerle oyuncu satın alımlarını izlemeye izin verin.

    1. Araç çubuğunun Ana Sayfa sekmesinde, Oyun Ayarları seçin.
    2. Navigate to the Güvenlik sekmesine gidin, ardından Studio Erişimini API Hizmetlerine Etkinleştir etkinleştirin.

Değerleri tanımla

Deneyiminizin kendi para birim sistemi varsa, bunları Çekirdek özelliği paketiyle tanımlayarak kaydedebilirsiniz, bunları ReplicatedStorage.FeaturePackagesCore.Configs.Currencies içinde tanımlayarak.Bu dosyada zaten bir Mücevher para biriminin yorumlanmış örneği var; kendinizle sahip ol.

Değerler

Gems = {
displayName = "Gems",
symbol = "💎",
icon = nil,
},

The Currencies script, Çekirdek özellik paketine para biriminizle ilgili bazı metadatlar söyler:

  • (gerekli) displayName - para birimibiriminizin adı. Bir sembol veya simge belirtmezseniz, bu adı satın alma düğmelerinde kullanılır ("100 Mücevher").
  • (isteğe bağlı) symbol - Eğer para birimi için simge olarak kullanılacak bir metin karakteriniz varsa, bunlar satın alma düğmelerindeki displayName yerine kullanılır (örneğin "💎100").
  • (isteğe bağlı) icon - Eğer para biriminiz için bir AssetId resim simgesine sahipseniz, satın alma düğmelerindeki displayName yerine kullanılır (yaniresim fiyatın soluna yerleştirilecek "🖼️100")

Para birimi ayarlanırken, bu bilgiler yerine paketin ilişkili geliştirici ürününden alınan bilgiler yerine başlık görüntüsü için paketin fiyatını, para birimini ve simgesini manuel olarak belirtmeniz gerekir.

Paketler

-- Bir geliştirici ürünü kullanmak istiyorsanız, yalnızca bir settarafından kullanılan benzersiz bir devProductId sağlamanız gerekir.
-- Geliştirici ürününden paket fiyatı ve simgeyi alacağız
pricing = {
priceType = CurrencyTypes.PriceType.Marketplace,
devProductId = 1795621566,
},
-- Aksi takdirde, bir geliştirici ürün yerine deneyim içi para birimini kullanmak istiyorsanız, şunu kullanabilirsiniz:
-- Buradaki fiyat deneyim içi para birimindedir, Robux değil
pricing = {
priceType = CurrencyTypes.PriceType.InExperience,
price = 79,
currencyId = "Gems",
icon = 18712203759,
},

Ayrıca BundlesExample kodunu çağırmak için setInExperiencePurchaseHandler koduna da referans vermeniz gerekir.

Paket Örneği

local function awardInExperiencePurchase(
_player: Player,
_bundleId: Types.BundleId,
_currencyId: CurrencyTypes.CurrencyId,
_price: number
)
-- Oyuncunun setsatın almak için yeterli para birimine sahip olup olmadığını kontrol edin
-- Oyuncu verilerini güncelle, eşyalar ver, vb.
-- oyuncupara birimini çıkar
task.wait(2)
return true
end
local function initializePurchaseHandlers()
local bundles = Bundles.getBundles()
for bundleId, bundle in bundles do
-- Paket, pazar fiyatı yazsahip değilse bir geliştirici ürünüyle bağlantılı değildir
if not bundle or bundle.pricing.priceType ~= "Marketplace" then
continue
end
Bundles.setPurchaseHandler(bundleId, awardMarketplacePurchase)
receiptHandlers[bundle.pricing.devProductId] = receiptHandler
end
-- Paketler için kullandığınız deneyim içi para birimleri varsa, burada tutucuyu ayarlayın
for currencyId, _ in Currencies do
Bundles.setInExperiencePurchaseHandler(currencyId, awardInExperiencePurchase)
end
end

Özellikle, örneğin awardInExperiencePurchase içinde bir döngü aracılığıyla adlandırılan Currencies doldurmanız gerekiyor, örneğin initializePurchaseHandlers (yaniher para birimi, elektronik cihaza Bundles.setInExperiencePurchaseHandler(currencyId, awardInExperiencePurchase) aracılığıyla bağlanır).

Paketleri tanımla

Deneyiminizde sunulabilecek tüm paketler aynı klasörde ReplicatedStorage.Bundles.Configs.Bundles , türleri ile ihraç edilerek tanımlanabilir ve Types kaydından çıkarılan kullanılan türler aynı klasörde.

Bir devProductId kullanıyorsanız, deneyiminizdeki ile eşleşen setana devProductId güncellemesini yapmanız gerekir.Bu, paketin kendisini satın almak için MarketplaceService ile talep edilecek olan şeydir. Paketin ayrı satışları takip etmesini kolaylaştırmak için yeni bir geliştirici ürünü kullanmak güçlü önerilir. Birden fazla öğeyi içeren bir paket istiyorsanız ve bunlar zaten deneyiminizde geliştirici ürünleri tarafından temsil ediliyorsa, ürün bilgileri aracılığıyla alınacak öğe fiyatı/assetId/isim belirtmenize gerek yoktur:

OKUMAK İçin README

{
itemType = ItemTypes.ItemType.DevProduct,
devProductId = <DEV_PRODUCT_ID>,
metadata = {
caption = {
text = "x1",
color = Color3.fromRGB(236, 201, 74),
} -- Altyazı isteğe bağlı! Bu alanı da atlayabilirsiniz
}
},

Aksi takdirde, bu öğe detaylarını manuel olarak yapılandırabilirsiniz:

OKUMAK İçin README

{
itemType = ItemTypes.ItemType.Robux,
priceInRobux = 49,
icon = <IMAGE_ASSET_ID>,
metadata = {
caption = {
text = "x1",
color = Color3.fromRGB(236, 201, 74),
} -- Altyazı isteğe bağlıdır! Bu alanı atlayabilirsiniz
}
},

Örneğin, tüm paketiniz muhtemelen şöyle görünecektir:

OKUMAK İçin README

local starterBundle: Types.RelativeTimeBundle = {
bundleType = Types.BundleType.RelativeTime,
-- Bir geliştirici ürünü kullanmak istiyorsanız, yalnızca bir settarafından kullanılan benzersiz bir devProductId sağlamanız gerekir.
-- Geliştirici ürününden paket fiyatı ve simgeyi alacağız
pricing = {
priceType = CurrencyTypes.PriceType.Marketplace,
devProductId = <DEV_PRODUCT_ID>,
},
-- Aksi takdirde, bir geliştirici ürün yerine deneyim içi para birimini kullanmak istiyorsanız, şunu kullanabilirsiniz:
-- Buradaki fiyat deneyim içi para birimindedir, Robux değil
-- fiyatlandırma = {
-- priceType = Para Türleri.PriceType.InExperience,
-- fiyat = 79,
-- paraId = <CURRENCY_ID>,
-- simge = <IMAGE_ASSET_ID>,
-- },
includedItems = {
[1] = {
-- Öğe kendisi geliştirici ürünü aracılığıyla satılmaz, bu nedenle Robux'ta ne kadar değerli olduğunu gösterin ve bir simge verin
-- The priceInRobux, paket fiyatına karşı paketin içeriğinin toplamına göre mutlak değer göstermeye yardımcı olur
itemType = ItemTypes.ItemType.Robux,
priceInRobux = 49,
icon = <IMAGE_ASSET_ID>,
-- Alternatif olarak, eğer bunun bir geliştirici ürünü varsa fiyat ve yukarıdaki simge bırakın ve sadece devProductId'yi ayarlayın
-- Fiyat ve simge geliştirici ürününden alınacak
-- devProductId = <ITEM_DEV_PRODUCT_ID>
-- Gerekirse UI'ye özgü daha fazla seçenekli veri alanı vardır
metadata = {
caption = {
text = "x1",
color = Color3.fromRGB(236, 201, 74),
},
},
},
[2] = {
itemType = ItemTypes.ItemType.Robux,
priceInRobux = 99,
icon = <IMAGE_ASSET_ID>,
metadata = {
caption = {
text = "x1",
color = Color3.fromRGB(236, 201, 74),
},
},
},
[3] = {
itemType = ItemTypes.ItemType.Robux,
priceInRobux = 149,
icon = <IMAGE_ASSET_ID>,
metadata = {
caption = {
text = "x1",
color = Color3.fromRGB(236, 201, 74),
},
},
},
},
singleUse = true, -- Satın alındıktan veya sona erdiğinde, deneyiminiz uyarıcıya tepki vermeye çalışsa bile artık geçerli değil. Bunu stüdyoda test ederken yapabilirsiniz.
durationInSeconds = 900, -- 15 dakika
includesOfflineTime = false, -- Sadece deneyimde geçen süre sayın
metadata = {
displayName = "STARTER BUNDLE",
description = "Save 75% and get a head start!",
},
}

Sunucu mantığını entegre et

Sunucunuzun ReplicatedStorage.Bundles.Server.Examples.BundlesExample ile nasıl etkileşime gireceğini gösteren Paketler özelliği paketi ve yukarıdaki yöntemler üzerinde nasıl etkileşime gireceğini göz atın ModuleScript .Aşağıdaki parçalar o senaryodan geliyor.

Ana olarak, deneyiminize Paketler özelliği paketini sürükledikten sonra dört şey bağlamanız gerekir:

  1. Satın alma işlemlerinin işlenmesi sırasında ödül öğelerine çağrılacak işlevleri belirtmek için satın alma elemanlarını Bundles.setPurchaseHandler aracılığıyla bağlayın.Connect purchase handlers through to specify the functions to call to award items when a purchase is being processed.

    Paket Örneği

    local function awardMarketplacePurchase(_player: Player, _bundleId: Types.BundleId, _receiptInfo: { [string]: any })
    -- Oyuncu verilerini güncelle, eşyalar ver, vb.
    -- ... VE alım bilgisi kaydedin, böylece kullanıcının zaten bu pakete sahip olup olmadığını kontrol edebiliriz
    task.wait(2)
    return Enum.ProductPurchaseDecision.PurchaseGranted
    end
    local function awardInExperiencePurchase(
    _player: Player,
    _bundleId: Types.BundleId,
    _currencyId: CurrencyTypes.CurrencyId,
    _price: number
    )
    -- Oyuncunun setsatın almak için yeterli para birimine sahip olup olmadığını kontrol edin
    -- Oyuncu verilerini güncelle, eşyalar ver, vb.
    -- oyuncupara birimini çıkar
    task.wait(2)
    return true
    end
    local function initializePurchaseHandlers()
    local bundles = Bundles.getBundles()
    for bundleId, bundle in bundles do
    -- Paket, pazar fiyatı yazsahip değilse bir geliştirici ürünüyle bağlantılı değildir
    if not bundle or bundle.pricing.priceType ~= "Marketplace" then
    continue
    end
    Bundles.setPurchaseHandler(bundleId, awardMarketplacePurchase)
    receiptHandlers[bundle.pricing.devProductId] = receiptHandler
    end
    -- Paketler için kullandığınız deneyim içi para birimleri varsa, burada tutucuyu ayarlayın
    for currencyId, _ in Currencies do
    Bundles.setInExperiencePurchaseHandler(currencyId, awardInExperiencePurchase)
    end
    end
  2. Mantığınızı MarketplaceService.ProcessReceipt için bağlayın, ancak deneyiminiz zaten satılıkolan geliştirici ürünleri varsa başka bir yerde yapılabilir.Temel olarak, bir geliştirici ürünü alınırken, şimdi ürünün bir setait olup olmadığını kontrol etmek için Bundles.getBundleByDevProduct 'yi arayacaklar.Eğer yaparsa, senaryo sonra Bundles.processReceipt 'yi arar.

    Paket Örneği

    -- Oyuncunun şarj edilmesi gerekip gerekmediğini belirlemek için pazardan alınan faturaları işle
    local function processReceipt(receiptInfo): Enum.ProductPurchaseDecision
    local userId, productId = receiptInfo.PlayerId, receiptInfo.ProductId
    local player = Players:GetPlayerByUserId(userId)
    if not player then
    return Enum.ProductPurchaseDecision.NotProcessedYet
    end
    local handler = receiptHandlers[productId] -- Ürün için tutucuyu alın
    local success, result = pcall(handler, receiptInfo, player) -- Satın alma mantığının başarılı olup olmadığını kontrol etmek için işleci arayın
    if not success or not result then
    warn("Failed to process receipt:", receiptInfo, result)
    return Enum.ProductPurchaseDecision.NotProcessedYet
    end
    return Enum.ProductPurchaseDecision.PurchaseGranted
    end
    local function receiptHandler(receiptInfo: { [string]: any }, player: Player)
    local bundleId, _bundle = Bundles.getBundleByProductId(receiptInfo.ProductId)
    if bundleId then
    -- Bu satın alma bir pakete ait, paketlerin halledmesine izin verin
    local purchaseDecision = Bundles.processReceiptAsync(player, bundleId, receiptInfo)
    return purchaseDecision == Enum.ProductPurchaseDecision.PurchaseGranted
    end
    -- Bu satın alma bir setait değil,
    -- ... varsa, mevcut tüm mantığı burada ele alın
    return false
    end
  3. Bağla Players.PlayerAdded:Connect(Bundles.OnPlayerAdded) böylece Paketler özelliği paketi bir oyuncu için henüz süresi dolmamış olan aktif paketleri yeniden soruyor.

    OKUMAK İçin README

    local function onPlayerAdded(player: Player)
    -- Oyuncu katıldığında paketlere söyleyin, böylece verilerini yeniden yükleyebilir
    Bundles.onPlayerAdded(player)
    -- Tüm yeni kullanıcılara sunmak istediğiniz bir başlangıç ​​paketiniz varsa, burada bunu talep edebilirsiniz
    -- ... Paketler oyuncunun zaten satın aldığını veya tekrarlanabilir olmadığından dolayı süresi dolduysa ele alacaktır
    -- Paketler.promptIfValidAsync(oyuncu, "Başlangıç Paketi")
    -- Bunu burada sadece örnek olarak çağırıyorsunuz, istediğiniz her an veya her yerde çağırabilirsiniz
    onPromptBundleXYZEvent(player)
    end
  4. Hızlı paketler. oynanışoynayışına bağlı olarak, örnek oyunculara bir Başlangıç Paketi ile onPlayerAdded uyarı verir.

    • Paketler özelliğinin paket mantığı, her oyuncunun setzaten satın almışsa tekrar teklif almadığını veya teklifin zaten sona erdiğini garanti eder (paket yapılandırmasına dayalı olarak).

    • Bir paketi bir oyuncuya göstermek istediğinizde, Bundles.promptIfValidAsync(player, bundleId) 'yi arayın.

    OKUMAK İçin README

    local function onPromptBundleXYZEvent(player: Player)
    -- Bir oyuncuya paketin ne zaman sorulacağını belirlemek için kullanmak istediğiniz herhangi bir deneyim set
    -- ... Bu, bir oyuncuya setgöndermek için uygunluk kriterlerinizi karşıladığınız her an olacaktır
    -- ... Örneğin, bir oyuncu katıldığında veya bir oyuncu seviye atladığında bir paket istemek istiyorsanız
    task.spawn(Bundles.promptIfValidAsync, player, <Some_Bundle_Id>)
    -- ... Çok sayıda paket oluşturuyorsanız, yukarıdaki işlev çağrısını sarma için task.spawn() kullanmak, sayım süreleri arasındaki farklılıkları azaltacaktır
    end

Alıntı kimliklerinin yedek kayıtları hakkındaki aşağıdaki en iyi uygulama önerilerini düşünün:

  • Paketler özelliği paketi aynı faturaları iki kez işlemeyi engellemek için ReceiptIds kaydediyor olsa da, satın alma işlemi işlemciyi satın aldıktan sonra başarısız olduğunda tablolarınızın içinde ReceiptIds kaydetmelisiniz, böylece bir sonraki yeniden denemede eşyaları tekrar ödül almayacağınızı bilirsiniz.

  • Paketler özelliği paketi, satın alma herhangi bir adımda başarısız olursa ReceiptId'yi kaydetmeyecektir, bu yüzden satın alma işlemi parçası olarak satın alıcınızda ReceiptId'yi kaydettiğinizden emin olmalısınız.

  • Bu redundans, tüm satın alma mantığının uygun bir şekilde ele alındığından ve veri depolarınızın ve Paketler özelliğinin paket veri deposunun nihai tutarlılığa ulaştığından emin olmaya yardımcı olur ve gerçek kaynak, veri depolarınız olur.

Konstantları yapılandır

Çekirdek özelliği paketi için sabitler iki noktada yaşıyor:

  • Paylaşılan sabitler ReplicatedStorage.FeaturePackagesCore.Configs.SharedConstants 'de yaşar.

  • Paket spesifik konular, bu durumda Paketler özelliği paketi, canlı olarak ReplicatedStorage.Bundles.Configs.Constants 'de yaşıyor.

Deneyiminizin tasarım gereksinimlerini karşılamak için ayarlamak istediğiniz ana şeyler:

  • Ses öğeleri ID'leri
  • Satın alma efekti süresi ve parça renkleri
  • Başa çıkma görüntü kırılganlığı

Ayrıca, çeviri için ayrılmış bir konuma sahip dize bulabilirsiniz: ReplicatedStorage.FeaturePackagesCore.Configs.TranslationStrings .

UI bileşenlerini özelleştirin

Renkler, yazı tipi ve transparans gibi paket nesnelerini değiştirerek, paket uyarılarının görsel sunumunu ayarlayabilirsiniz.Ancak, hiyerarşik olarak herhangi bir nesneyi hareket ettirirseniz, kodun onları bulamayacağını ve kodunuzu ayarlamak zorunda kalacağınızı unutmayın.

Bir istemci iki yüksek seviye bileşenden oluşur:

  • PromptItem – Paket içinde her bir öğe için tekrarlanan bireysel bileşen (öğe resmi, başlık, adı, fiyat).
  • Prompt – Açılır pencere kendisi.

Başlık görüntüsü de iki bileşenden oluşur:

  • HudItem – Başlık görüntüsünde her menü seçeneğini temsil eden bir bileşen.
  • Hud – Programatik olarak doldurulmak için HudItems ile doldurulacak.

Kafalar üzerinde daha fazla kontrol sahibi olmak istiyorsanız, sadece mevcut HUD UI'yi ReplicatedStorage.Bundles.Objects.BundlesGui içinde kullanmak yerine, kendi tasarım gereksinimlerinizi karşılamak için şeyleri hareket ettirebilirsiniz.Sadece ReplicatedStorage.Bundles.Client.UIController scriptinde istemci senaryo davranışını güncellemekten emin olun.

API referansı

Türler

Nispi Süre

Bir oyuncuya RelativeTime paketi teklif edildiğinde, süre dolana kadar kullanılabilir olur.Bu tür, oyuncunun başında görüntülenir ve paket sona erene kadar veya oyuncu satın alana kadar gelecekteki oturumlar için otomatik olarak sorar.

Bu paket türünün yaygın bir örneği, 24 saat boyunca tüm yeni oyunculara gösterilen tek kullanımlık başlangıç ​​paketi teklifidir.Başlangıç paketi paketlerini nasıl uygulayacağınızla ilgili endüstri en iyi uygulamalarına bakın Başlangıç Paketi Tasarımı.

AdıTürAçıklama
includeOfflineTimebool (Opsiyonel) Eğer ayarlanmazsa, sadece deneyimde geçirilen süre kalan teklif süresine sayılacaktır.
singleUsebool (Opsiyonel) Eğer ayarlanmazsa, satın alma işlemi satın alındıktan veya sona erdiğinde yeniden etkinleştirilebilir.Eğer ayarlanırsa, bir kez satın alındıktan veya sona erdiğinde, paketId ile çağrılan Bundles.promptIfValidAsync ile bir daha asla sorun yok olmayacaktır, hatta eğer çağrırsanız.

Sabit Süre

Bir oyuncuya FixedTime paketi teklif edildiğinde, koordine edilen evrensel sürenin sonuna kadar kullanılabilir olur.Bu tür, oyuncunun başında görüntülenir ve paket sona erene kadar veya oyuncu satın alana kadar gelecekteki oturumlar için otomatik olarak sorar.

Bu paket türünün yaygın bir örneği, sadece belirli bir ay için mevcut olan bir tatil teklifidir.

Tek Seferlik

Bir OneTime paketi yalnızca bir oyuncuya teklif edildiğinde mevcut olur.Oyuncunun başında görüntülenmez ve bir oyuncu istemiyi kapattığında, tekrar sunucu tarafından talep edilene kadar tekrar açılamaz.

Bu paket türünün yaygın bir örneği, bir oyuncunun tükenmesinin anında daha fazla deneyim para satın alma teklifidir.