Bündel-Paket

*Dieser Inhalt wurde mit KI (Beta) übersetzt und kann Fehler enthalten. Um diese Seite auf Englisch zu sehen, klicke hier.

Das Bündel -Funktionspaket bietet eine Out-of-the-Box-Funktionalität, um Sammlungen von Artikeln an Spieler mit Rabatt zu verkaufen.Du kannst wählen, ob Spieler Bündel mit einer benutzerdefinierten In-Experience-Währung oder Robux kaufen sollen oder welchen Bündeltyp du verwenden möchtest, welche Artikel du verkaufen möchtest und wie du Spieler während ihres Gameplayauffordern möchtest.

Mit den Anpassungsoptionen des Pakets können Sie Ihre Pakete anpassen, um die Design- und Monetarisierungsziele Ihrer Erlebnisse zu erfüllen, wie:

  • Zielrichtung einer niedrigen Umwandlungsrate, indem kostengünstige Starterpakete angeboten werden, die neuen Spielern einen Mehrwert bieten und sie zu frühen Ausgaben ermutigen.
  • Erhöhung der Ausgabetiefe durch das Bündeln von Artikeln an verschiedenen Preispunkten, um eine Reihe von Spielern anzusprechen.
  • Monetarisierung von Live-Operationen (LiveOps) Events durch Angebot von zeitlich begrenzten Bündeln exklusiver Artikel.

Paket erhalten

Der Creator-Store ist ein Tab der Toolbox, den Sie verwenden können, um alle Assets zu finden, die von Roblox und der Roblox-Community erstellt wurden, um sie in Ihren Projekten zu verwenden, einschließlich Modell, Bild, Mesh, Audiodateien, Plug-in, Video und Schriftarten.Du kannst den Creator-Store verwenden, um eine oder mehrere Assets direkt in ein offenes Erlebnis einzufügen, einschließlich Feature-Pakete!

Jedes Feature-Paket erfordert, dass das Kern -Feature-Paket ordnungsgemäß funktioniert.Sobald die Kern - und Bündel -Funktionspaket-Assets in deinem Inventar sind, kannst du sie in jedem Projekt auf der Plattform wiederverwenden.

Um die Pakete aus deinem Inventar in deine Erlebniszu bringen:

  1. Füge das Kern - und Bündel -Funktionspaket zu deinem Inventar innerhalb von Studio hinzu, indem du auf die Schaltfläche Zum Inventar hinzufügen in der folgenden Reihe von Komponenten klickst.

  2. Wählen Sie in der Toolbar die Ansicht-Registerkarte.

  3. Klicken Sie auf Werkzeugkiste . Das Werkzeugkistenfenster wird angezeigt.

    Studio's View tab with the Toolbox tool highlighted.
  4. In dem Werkzeugkasten Fenster klicken Sie auf die Inventar Registerkarte. Die meine Modelle Sortierung wird angezeigt.

    Studio's Toolbox window with the Inventory tab highlighted.
  5. Klicken Sie auf die Feature-Paket-Kern -Kachel, dann auf die Bündel-Funktionspaket -Kachel.Beide Paketordner werden im Explorer -Fenster angezeigt.

  6. Ziehe die PaketOrdner in ReplicatedStorage .

  7. Erlaube Datenlagern, Anrufe zu verfolgen, mit denen Spielerkäufe mit den Paketen getätigt werden.

    1. Wählen Sie auf der Registerkarte Home der Toolbar Spieleinstellungen .
    2. Navigiere zur Sicherheits -Registerkarte und aktiviere dann Studio-Zugriff auf API-Dienste aktivieren .

Währungen definieren

Wenn deine Erfahrung ein eigenes Währungssystem hat, kannst du sie mit dem Kern -Funktionspaket registrieren, indem du sie in ReplicatedStorage.FeaturePackagesCore.Configs.Currencies definierst.Es gibt bereits ein kommentiertes Beispiel für eine Edelstein-Währung in dieser Datei; ersetze es durch besitzen.

Währungen

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

Das Currencies-Skript sagt dem Kern -Funktionspaket einige Metadaten über Ihre Währung:

  • (erforderlich) displayName - Der Name deiner Währung. Wenn du kein Symbol oder ein Icon spezifizierst, wird dieser Name in Kauf buttons verwendet (z. B. "100 Edelsteine").
  • (optional) symbol - Wenn du einen Textzeichen als Symbol für deine Währung verwenden möchtest, wird dies anstelle des displayName in Kauf buttons (z. B. "💎100") verwendet.
  • (optional) icon - Wenn du ein AssetId Bildsymbol für deine Währung hast, wird dies anstelle des displayName in Kauf buttons verwendet (d.h.Das Bild wird links vom Preis "🖼️100") platziert

Sobald deine Währung eingerichtet ist, musst du den Preis, die Währung und das Symbol des Bündels für die Vorschauanzeige manuell angeben, anstatt dass diese Informationen vom verbundenen Entwicklerprodukt des Bündels abgerufen werden.

Bündel

-- Wenn du ein Entwicklerprodukt verwenden möchtest, musst du eine eindeutige devProductId liefern, die nur von einem Bündel verwendet wird.
-- Wir werden den Bündelpreis und das Symbol vom Entwicklerprodukt abrufen
pricing = {
priceType = CurrencyTypes.PriceType.Marketplace,
devProductId = 1795621566,
},
-- Andernfalls, wenn du stattdessen zur Erfahrungswährung anstelle eines Entwicklerprodukts verwenden möchtest, kannst du stattdessen Folgendes verwenden:
-- Preis hier ist in der Währung, nicht in Robux
pricing = {
priceType = CurrencyTypes.PriceType.InExperience,
price = 79,
currencyId = "Gems",
icon = 18712203759,
},

Du musst auch das BundlesExample-Skript referenzieren, um setInExperiencePurchaseHandler aufzurufen.

Bündelbeispiel

local function awardInExperiencePurchase(
_player: Player,
_bundleId: Types.BundleId,
_currencyId: CurrencyTypes.CurrencyId,
_price: number
)
-- Überprüfe, ob der Spieler über genug Währung verfügt, um das Bündel zu kaufen
-- Aktualisieren Sie Spielerdaten, geben Sie Artikel usw.
-- Subtrahiere die Währung vom Spieler:in
task.wait(2)
return true
end
local function initializePurchaseHandlers()
local bundles = Bundles.getBundles()
for bundleId, bundle in bundles do
-- Bündel ist nicht mit einem Entwicklerprodukt verbunden, wenn es keinen eingebenhat
if not bundle or bundle.pricing.priceType ~= "Marketplace" then
continue
end
Bundles.setPurchaseHandler(bundleId, awardMarketplacePurchase)
receiptHandlers[bundle.pricing.devProductId] = receiptHandler
end
-- Wenn du irgendwelche In-Experience-Währungen hast, die du für Bündel verwendest, lege den Handler hier fest
for currencyId, _ in Currencies do
Bundles.setInExperiencePurchaseHandler(currencyId, awardInExperiencePurchase)
end
end

Insbesondere musst du awardInExperiencePurchase ausfüllen, was durch eine Schleife durch Currencies innerhalb des Beispiels initializePurchaseHandlers (d.h.jede WährungID ist mit dem Handler durch Bundles.setInExperiencePurchaseHandler(currencyId, awardInExperiencePurchase) verbunden).

Bündel definieren

Alle Pakete, die in deiner Erfahrung angeboten werden können, können innerhalb von ReplicatedStorage.Bundles.Configs.Bundles definiert werden, mit Typs, die aus dem Types Skript im gleichen Ordner exportiert werden.

Wenn du eine devProductId verwendest, musst du das Haupt-devProductId des Bündels aktualisieren, um es mit dem in deiner Erlebnisübereinzubringen.Das ist, was durch MarketplaceService zum Kauf des Bündels selbst aufgefordert wird. Es wird dringend empfohlen, ein neues Entwicklerprodukt für das Bündel zu verwenden, um es einfacher zu machen, separate Verkäufe zu verfolgen. Wenn du ein Bündel mit mehreren Artikeln möchtest, und wenn diese bereits durch Entwicklerprodukte in deiner Erlebnisrepräsentiert sind, musst du den Artikelpreis/AssetId/Name nicht explizit festlegen, der über Produktinformationen abgerufen wird:

LESEN Sie ME

{
itemType = ItemTypes.ItemType.DevProduct,
devProductId = <DEV_PRODUCT_ID>,
metadata = {
caption = {
text = "x1",
color = Color3.fromRGB(236, 201, 74),
} -- Untertitel ist optional! Du kannst auch dieses Feld überspringen
}
},

Ansonsten kannst du diese Artikeldetails manuell konfigurieren:

LESEN Sie ME

{
itemType = ItemTypes.ItemType.Robux,
priceInRobux = 49,
icon = <IMAGE_ASSET_ID>,
metadata = {
caption = {
text = "x1",
color = Color3.fromRGB(236, 201, 74),
} -- Untertitel ist optional! Sie können auch dieses Feld überspringen
}
},

Zum Beispiel wird dein gesamtes Bündel wahrscheinlich so aussehen:

LESEN Sie ME

local starterBundle: Types.RelativeTimeBundle = {
bundleType = Types.BundleType.RelativeTime,
-- Wenn du ein Entwicklerprodukt verwenden möchtest, musst du eine eindeutige devProductId liefern, die nur von einem Bündel verwendet wird.
-- Wir werden den Bündelpreis und das Symbol vom Entwicklerprodukt abrufen
pricing = {
priceType = CurrencyTypes.PriceType.Marketplace,
devProductId = <DEV_PRODUCT_ID>,
},
-- Andernfalls, wenn du stattdessen zur Erfahrungswährung anstelle eines Entwicklerprodukts verwenden möchtest, kannst du stattdessen Folgendes verwenden:
-- Preis hier ist in der Währung, nicht in Robux
-- preis = {
-- preistyp = Währungstypen.Preistyp.InExperience,
-- preis = 79,
-- WährungId = <CURRENCY_ID>,
-- icon = <IMAGE_ASSET_ID>,
-- },
includedItems = {
[1] = {
-- Das Item selbst wird nicht über ein Entwicklerprodukt verkauft, also gib an, wie viel es in Robux wert ist, und gib ein Icon
-- Der PreisInRobux hilft Bündeln, den relativen Wert des Bündelpreises gegenüber der Summe seiner Inhalte anzuzeigen
itemType = ItemTypes.ItemType.Robux,
priceInRobux = 49,
icon = <IMAGE_ASSET_ID>,
-- Alternativ, wenn dies ein Entwicklerprodukt hat, lassen Sie den Preis und das Symbol oben weg und stellen Sie nur die devProductId ein
-- Der Preis und das Icon werden aus dem Entwicklerprodukt abgerufen
-- devProductId = <ITEM_DEV_PRODUCT_ID>
-- Es gibt mehr optionale Metadatenfelder, die bei Bedarf UI-spezifisch sind
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, -- Sobald gekauft oder abgelaufen, ist es nicht mehr gültig, auch wenn deine Erfahrung versucht, zu fragen (onPlayerAdded). Du kannst dies während des Tests im Studio falsch machen.
durationInSeconds = 900, -- 15 minuten
includesOfflineTime = false, -- Zähle nur die Zeit, die im Erlebnis verstrichen ist
metadata = {
displayName = "STARTER BUNDLE",
description = "Save 75% and get a head start!",
},
}

Serverlogik integrieren

Schau dir ReplicatedStorage.Bundles.Server.Examples.BundlesExample an, das zeigt, wie dein Server mit dem Bundles Feature-Paket und den oben genannten Methoden auf der ModuleScript interagieren wird.Die Snippets unten sind aus diesem Skript, das. PL: die Skripts.

Du musst vor allem vier Dinge verbinden, sobald du das Bündel -Funktionspaket in deine Erlebnisziehst:

  1. Verbinde Kaufbearbeiter durch Bundles.setPurchaseHandler mit, um die Funktionen anzugeben, die zum Anrufen von Artikeln bei einem Kauf verwendet werden sollen, wenn ein Kauf bearbeitet wird.

    Bündelbeispiel

    local function awardMarketplacePurchase(_player: Player, _bundleId: Types.BundleId, _receiptInfo: { [string]: any })
    -- Aktualisieren Sie Spielerdaten, geben Sie Artikel usw.
    -- ... UND record receiptInfo.PurchaseId, damit wir überprüfen können, ob der Benutzer dieses Bündel bereits hat
    task.wait(2)
    return Enum.ProductPurchaseDecision.PurchaseGranted
    end
    local function awardInExperiencePurchase(
    _player: Player,
    _bundleId: Types.BundleId,
    _currencyId: CurrencyTypes.CurrencyId,
    _price: number
    )
    -- Überprüfe, ob der Spieler über genug Währung verfügt, um das Bündel zu kaufen
    -- Aktualisieren Sie Spielerdaten, geben Sie Artikel usw.
    -- Subtrahiere die Währung vom Spieler:in
    task.wait(2)
    return true
    end
    local function initializePurchaseHandlers()
    local bundles = Bundles.getBundles()
    for bundleId, bundle in bundles do
    -- Bündel ist nicht mit einem Entwicklerprodukt verbunden, wenn es keinen eingebenhat
    if not bundle or bundle.pricing.priceType ~= "Marketplace" then
    continue
    end
    Bundles.setPurchaseHandler(bundleId, awardMarketplacePurchase)
    receiptHandlers[bundle.pricing.devProductId] = receiptHandler
    end
    -- Wenn du irgendwelche In-Experience-Währungen hast, die du für Bündel verwendest, lege den Handler hier fest
    for currencyId, _ in Currencies do
    Bundles.setInExperiencePurchaseHandler(currencyId, awardInExperiencePurchase)
    end
    end
  2. Verbinde deine Logik für MarketplaceService.ProcessReceipt, aber das kann an anderer Stelle erledigt werden, wenn deine Erfahrung bereits Entwicklerprodukte zum Verkauf stehenhat.Im Wesentlichen wird beim Verarbeiten einer Entwicklerproduktrechnung nun Bundles.getBundleByDevProduct angerufen, um zu überprüfen, ob das Produkt zu einem Bündel gehört.Wenn es das tut, ruft das Skript dann Bundles.processReceipt auf.

    Bündelbeispiel

    -- Prozessrezept vom Marktplatz, um zu bestimmen, ob der Spieler belastet werden muss oder nicht
    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] -- Holen Sie sich den Handler für das Produkt
    local success, result = pcall(handler, receiptInfo, player) -- Rufen Sie den Handler auf, um zu überprüfen, ob die Kauflogik erfolgreich ist
    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
    -- Dieser Kauf gehört zu einem Bündel, lassen Sie Bündel es handhaben
    local purchaseDecision = Bundles.processReceiptAsync(player, bundleId, receiptInfo)
    return purchaseDecision == Enum.ProductPurchaseDecision.PurchaseGranted
    end
    -- Dieser Kauf gehört nicht zu einem Bündel,
    -- ... behandle alle deine vorhandene Logik hier, wenn du irgendwelche hast
    return false
    end
  3. Verbinde Players.PlayerAdded:Connect(Bundles.OnPlayerAdded), damit das Feature-Paket Bündel erneut aktive Bündel fragt, die für einen Spieler:innoch nicht abgelaufen sind.

    LESEN Sie ME

    local function onPlayerAdded(player: Player)
    -- Sage Bundles, wenn Spieler beitreten, damit es ihre Daten neu laden kann
    Bundles.onPlayerAdded(player)
    -- Wenn du ein Starter-Paket hättest, das du allen neuen Benutzern anbieten wolltest, könntest du das hier einfordern
    -- ... Bündel werden umgehen, wenn der Spieler es bereits gekauft hat oder es abgelaufen ist, da es nicht wiederholbar ist
    -- Bündel.promptIfValidAsync(Spieler:in, "StarterBundle")
    -- Wenn du das hier nur zum Beispiel aufrufst, kannst du es jederzeit und überall aufrufen, wann immer du willst
    onPromptBundleXYZEvent(player)
    end
  4. Schnelle Pakete. Während dies vom Gameplayabhängt, zeigt das Beispiel den Spielern mit einem Starter-Bündel onPlayerAdded an.

    • Die Bündel -Funktionspaketlogik gewährleistet, dass jeder Spieler kein wiederholtes Angebot erhält, wenn er das Bündel bereits gekauft hat oder das Angebot bereits abgelaufen ist (basierend auf Bündelkonfiguration).

    • Wann immer du ein Bündel einem Spieler:inanzeigen möchtest, rufe Bundles.promptIfValidAsync(player, bundleId) an.

    LESEN Sie ME

    local function onPromptBundleXYZEvent(player: Player)
    -- Verbinde jedes Erlebnisevent, das du verwenden möchtest, um festzustellen, wann ein Spieler aufgefordert wird, das Bündel zu erhalten
    -- ... das wird immer sein, wenn du deine Elegibilitätskriterien erfüllt hast, um einen Spieler das Bündel zu präsentieren
    -- ... Wenn du beispielsweise ein Bündel auffordern möchtest, wenn ein Spieler beitritt oder wenn ein Spieler aufsteigt
    task.spawn(Bundles.promptIfValidAsync, player, <Some_Bundle_Id>)
    -- ... Wenn mehrere Bündel erstellt werden, wird die Verwendung von task.Spawn() dazu beitragen, Diskrepanzen zwischen Countdowns zu minimieren
    end

Betrachte die folgenden Best Practise-Anweisungen zur redundanten Aufzeichnung von ReceiptIds:

  • Während das Bündel -Funktionspaket ReceiptIDs aufzeichnet, um zu vermeiden, dass die gleiche Rechnung zweimal verarbeitet wird, solltest du auch ReceiptIDs innerhalb deiner Tabellen aufzeichnen, damit du weißt, dass du bei einem Fehlschlag des Kaufprozesses nachdem dein Kaufverarbeiter bereits fertig ist, keine Artikel erneut vergeben sollst.

  • Das Bündel -Funktionspaket wird die ReceiptId nicht aufzeichnen, wenn der Kauf bei einem Schritt fehlschlägt, also solltest du sicherstellen, dass du die ReceiptId in deinen Tabellen aufzeichnest, bevor du die Receipt als Teil deines PurchaseHandlers verarbeitest.

  • Diese Redundanz hilft sicherzustellen, dass die gesamte Kauflogik angemessen behandelt wurde und der Datenstore Ihres Datenlagers und der Datenstore des Bundles Feature-Pakets letztendlich konsistent werden, wobei der Datenstore Ihrer Datenquelle die Quelle der Wahrheit ist.

Konfigurieren von Konstanten

Konstanten für das Kern -Funktionspaket sind live in zwei Orten:

  • Geteilte Konstanten leben in ReplicatedStorage.FeaturePackagesCore.Configs.SharedConstants.

  • Paket spezifische Konstanten, in diesem Fall das Bündel Feature-Paket, leben in ReplicatedStorage.Bundles.Configs.Constants .

Die wichtigsten Dinge, die du anpassen möchtest, um die Designanforderungen deines Erlebnisses zu erfüllen:

  • Klang-AssetIDs
  • Kaufeffektdauer und Partikelfarben kaufen
  • Kopfbedienungskollapsibilität anzeigen

Zusätzlich können Sie Zeichen für die Übersetzung in eine einzige Position aufteilen: ReplicatedStorage.FeaturePackagesCore.Configs.TranslationStrings .

UI-Komponenten anpassen

Durch Änderung der Paketobjekte wie Farben, Schriftart und Transparenz kannst du die visuelle Präsentation deiner Bündelaufforderungen anpassen.Beachte jedoch, dass, wenn du eines der Objekte hierarchisch umstellst, der Code sie nicht finden kann und du Änderungen an deinem Codesvornehmen musst.

Ein Prompt besteht aus zwei hohen Komponenten:

  • PromptItem – Die einzelne Komponente wiederholt sich für jedes Element innerhalb eines Bündels (Artikelbild, Untertitel, Name, Preis).
  • Prompt – Das Eingabeaufforderungsfenster selbst.

Das Kopfzeichenanzeige besteht auch aus zwei Komponenten:

  • HudItem – Eine einzelne Komponente, die jede Menüoption im Kopfaussteller darstellt.
  • Hud – Um mit programmatisch mit HudItems gefüllt zu werden.

Wenn du mehr Kontrolle über das Kopfbedienfeld haben möchtest, anstatt nur die vorhandene HUD-Benutzeroberfläche innerhalb von ReplicatedStorage.Bundles.Objects.BundlesGui zu verwenden, kannst du die Dinge verschieben, um deinen eigenen Designanforderungen zu entsprechen.Stellen Sie nur sicher, dass Sie das Client-Skriptverhalten im ReplicatedStorage.Bundles.Client.UIController Skript, das. PL: die Skriptsaktualisieren.

API-Referenz

Arten

Relative Zeit

Sobald das RelativeTime Bündel einem Spieler:inangeboten wird, bleibt es bis zur Ablaufzeit der Zeitdauer verfügbar.Dieser Typ wird auf dem Hauptbildschirm des Spieler:inangezeigt und fragt automatisch in zukünftigen Sitzungen nach, bis das Bündel abläuft oder der Spieler es kauft.

Ein häufiges Beispiel für diesen Bündeltyp ist ein einmalige Starterpaketangebot, das für 24 Stunden allen neuen Spielern angezeigt wird.Für branchenbestimmte Praktiken zur Implementierung von Starter-Paket-Bündeln siehe Starter-Paket-Design.

NamenTypBeschreibung
includeOfflineTimebool (Optional) Wenn nicht festlegen, zählt nur die Zeit, die in der Erfahrung verbracht wird, zur verbleibenden Angebotsdauer.
singleUsebool (Optional) Wenn es nicht festlegenist, kann der Kauf nach dem Kauf oder Ablauf wieder aktiviert werden.Wenn es festlegenist, kann es einmal gekauft oder abgelaufen werden, bevor es zum ersten Mal gekauft oder abgelaufen wird, auch wenn Sie Bundles.promptIfValidAsync mit dem BündelId anrufen.

Fixierte Zeit

Sobald das FixedTime Bündel einem Spieler:inangeboten wird, bleibt es bis zum Ende der koordinierten universellen Zeit (UTC) verfügbar.Dieser Typ wird auf dem Hauptbildschirm des Spieler:inangezeigt und fragt automatisch in zukünftigen Sitzungen nach, bis das Bündel abläuft oder der Spieler es kauft.

Ein häufiges Beispiel für diesen Bündeltyp ist ein Urlaubsangebot, das nur für einen bestimmten Monat verfügbar ist.

Einmalig

Ein OneTime-Paket ist nur verfügbar, wenn es einem Spieler:inangeboten wird.Es wird nicht auf dem Hauptbildschirm des Spieler:inangezeigt, und sobald ein Spieler die Aufforderung schließt, kann sie nicht wieder geöffnet werden, bis sie vom Server erneut angezeigt wird.

Ein häufiges Beispiel für diesen Bündeltyp ist ein Angebot, mehr Erfahrungswährung zu kaufen, sobald ein Spieler ausgeht.