Share via


Spielerinventar

Anforderungen

Um das Spielerinventar verwenden zu können, muss ein Katalog für Ihren Titel definiert sein. Weitere Informationen finden Sie in unserem Katalog-Tutorial.

Notiz

Optional können Sie auch Stores für Ihren Katalog definieren.

Während ein Katalog die Liste aller im Spiel verfügbaren Artikel ist, ist ein Store eine Teilmenge der Artikel aus dem Katalog, für die eine eindeutige Preisgestaltung möglich ist.

Pro Katalog können mehrere Stores definiert werden, sodass Sie je nach Benutzersegmentierung oder anderen Faktoren unterschiedliche Sätze von Elementen festlegen können, die Sie dem Spieler präsentieren.

Nachdem Sie einen Katalog über den Game Manager oder über unsere SetCatalogItems- oder UpdateCatalogItems-API-Aufrufe des Administrators definiert haben, können Sie eine Vielzahl von Inventory-API-Aufrufen auf dem Client und Server verwenden.

API-Übersicht

Alle Inventar-API-Aufrufe sind serverberechtigt und sicher. Bei richtiger Verwendung können Kunden keinen Betrug begehen oder Gegenstände erwerben, die sie nicht verdient haben.

Clients:

Server:

Das unten gezeigte Beispiel veranschaulicht die Codeblöcke, die diese API-Methoden aufrufen, und richtet grundlegende Anwendungsfälle für das Spielerinventar ein.

Notiz

Diese Beispiele stammen aus Unicorn Battle, einem Spiel, das wir als Beispiel zur Demonstration der PlayFab-Features entwickelt haben.

Die unten verwendete virtuelle Währung AU ist Gold, eine kostenlose Währung, die im Kampf gegen Monster verdient werden kann (siehe unser Lernprogramm zu Währungen).

Bevor wir beginnen, definieren wir einige Hilfsprogrammfunktionen, die in den meisten Beispielen in diesem Guide verwendet und wiederverwendet werden.

// **** Shared example utility functions ****

// This is typically NOT how you handle success
// You will want to receive a specific result-type for your API, and utilize the result parameters
void LogSuccess(PlayFabResultCommon result) {
    var requestName = result.Request.GetType().Name;
    Debug.Log(requestName + " successful");
}

// Error handling can be very advanced, such as retry mechanisms, logging, or other options
// The simplest possible choice is just to log it
void LogFailure(PlayFabError error) {
    Debug.LogError(error.GenerateErrorReport());
}

Client-only-Beispiel: Einen Heiltrank kaufen und konsumieren

Client-API-Aufrufreihenfolge: PurchaseItem, GetUserInventory, ConsumeItem

Zunächst müssen wir den Artikel in unserem Katalog definieren.

PlayFab – Wirtschaft – Katalogelement bearbeiten

Dies sind die CatalogItem-Anforderungen an den Heiltrank:

  • PurchaseItem erfordert einen positiven Artikelpreis (5 AU).
  • ConsumeItemerfordert, dass das Element mit einer positiven Elementanzahl (3) sein mussConsumable.
  • Der Spieler, der den Kauf tätigt, muss über 5 AU in seinem virtuellen Währungsguthaben verfügen.

Der Code für jeden Aufruf ist unten angegeben.

void MakePurchase() {
    PlayFabClientAPI.PurchaseItem(new PurchaseItemRequest {
        // In your game, this should just be a constant matching your primary catalog
        CatalogVersion = "CharacterClasses",
        ItemId = "MediumHealthPotion",
        Price = 5,
        VirtualCurrency = "AU"
    }, LogSuccess, LogFailure);
}

void GetInventory() {
    PlayFabClientAPI.GetUserInventory(new GetUserInventoryRequest(), LogSuccess, LogFailure);
}

void ConsumePotion() {
    PlayFabClientAPI.ConsumeItem(new ConsumeItemRequest {
        ConsumeCount = 1,
        // This is a hex-string value from the GetUserInventory result
        ItemInstanceId = "potionInstanceId"
    }, LogSuccess, LogFailure);
}

Beispiel: Dem Spieler wird ein Container gewährt, und er öffnet diesen

API-Aufrufreihenfolge:

Zunächst müssen wir mit einem Container beginnen, der in unserem Katalog definiert ist. Für den Container in diesem Beispiel haben wir einen CrystalContainer ausgewählt.

In diesem Beispiel wird auch das Öffnen des Containers mit einem Schlüssel veranschaulicht. Dies ist ein optionales Element, das sich auch im Spielerinventar befinden muss, damit der UnlockContainerInstance-Aufruf erfolgreich ist.

PlayFab – Wirtschaft – Katalogcontainer bearbeiten

CatalogItem Zu den Anforderungen für unseren CrystalContainer in diesem Beispiel gehören:

  • Dieser CrystalContainer muss als Container definiert werden.

  • Diese Container müssen optional ein Schlüsselelement definieren können, das dann zum Freischalten des Containers erforderlich ist – in diesem Fall ein CrystalKey.

  • Es wird dringend empfohlen, dass Ihr Container und alle Schlüsselbeidemit einer positiven Nutzungsanzahl nutzbar sind, sodass sie nach der Verwendung aus dem Spielerbestand entfernt werden.

Servercode

void GrantItem() {
    PlayFabServerAPI.GrantItemsToUser(new GrantItemsToUserRequest {
        // In your game, this should just be a constant
        CatalogVersion = "CharacterClasses",
        // Servers must define which character they're modifying in every API call
        PlayFabId = "playFabId",
        ItemIds = new List<string> { "CrystalContainer" }
    }, LogSuccess, LogFailure);
}

Clientcode

void OpenContainer() {
    PlayFabClientAPI.UnlockContainerInstance(new UnlockContainerInstanceRequest {
        // In your game, this should just be a constant matching your primary catalog
        CatalogVersion = "CharacterClasses",
        ContainerItemInstanceId = "containerInstanceId",
        KeyItemInstanceId = "keyInstanceId"
    }, LogSuccess, LogFailure);
}

Nutzung von Schlüsseln und Containern

Im vorherigen Beispiel haben wir vorgeschlagen, den Schlüssel bzw. den Container als konsumierbar zu definieren, dies ist jedoch nur eine Empfehlung.

Wenn ein Container und sein Schlüssel (falls vorhanden) jedoch nicht konsumierbar sind, kann der Container unendlich oft geöffnet werden, wobei sein Inhalt dem Spieler jedes Mal gewährt wird.

Da die Inventarkapazität des Spielers nicht unendlich ist, wird von diesem Muster dringend abgeraten. Wenn ein konsumierbarer Container freigeschaltet wird, verringert sich automatisch die Nutzungsanzahl sowohl für ihn als auch für den verwendeten konsumierbaren Schlüssel, und diese werden aus dem Spielerinventar entfernt, wenn die Nutzungsanzahl Null erreicht.

Mögliche Optionen

Konsumierbarer Container, kein Schlüssel: Das grundlegendste Muster, bei dem der Container beim Öffnen verbraucht wird und es keinen Schlüssel gibt.

Konsumierbarer Container, konsumierbarer Schlüssel: Der einfache Fall eines gesperrten Containers, der dem Spieler erlaubt, den Container mit dem Schlüssel zu öffnen. Beide werden verbraucht, und der Spieler kann nur einen Container mit verbleibenden Verwendungen mit einem Schlüssel mit verbleibenden Verwendungen öffnen.

Dauerhafter Container, konsumierbare Schlüssel: Auf diese Weise kann ein Spieler den Container jedes Mal öffnen, wenn er einen Schlüssel findet. Der Schlüssel wird verbraucht und der Container wird nur geöffnet, solange für den Schlüssel noch verbleibende Verwendungen vorhanden sind.

Konsumierbarer Container, dauerhafter Schlüssel: Auf diese Weise kann ein Spieler einen Schlüssel behalten, mit dem alle Container geöffnet werden können, für die dieser der Schlüssel ist. Der Container wird konsumiert, aber der Spieler behält die Möglichkeit, Container später mit dem Schlüssel zu öffnen.

Beispiel: Kauf von Inventargegenständen vom Spieler

Es gibt keine integrierte API für den Rückkauf von Inventargegenständen vom Spieler, da der Vorgang spielspezifisch ist. Sie können jedoch die vorhandenen API-Methoden verwenden, um Ihre eigene SellItem-Erfahrung zu erstellen:

  • Mit der PlayFab Server-API RevokeInventoryItem** können Sie ein Inventarelement entfernen.

  • Die PlayFab Server-API AddUserVirtualCurrency** kann eine entsprechende Menge an virtueller Währung zurückgeben. Es ist derzeit nicht möglich, echtes Geld über PlayFab-API-Methoden zurückzugeben.

Notiz

Artikel und virtuelle Währungen stehen in enger Beziehung zueinander. Weitere Informationen finden Sie in unserem Lernprogramm Währungen.

Die folgende CloudScript-Funktion kombiniert die beiden beschriebenen Serveraufrufe zu einem einzigen clientzugänglichen Aufruf.

var SELL_PRICE_RATIO = 0.75;
function SellItem_internal(soldItemInstanceId, requestedVcType) {
    var inventory = server.GetUserInventory({ PlayFabId: currentPlayerId });
    var itemInstance = null;
    for (var i = 0; i < inventory.Inventory.length; i++) {
        if (inventory.Inventory[i].ItemInstanceId === soldItemInstanceId)
            itemInstance = inventory.Inventory[i];
    }
    if (!itemInstance)
        throw "Item instance not found"; // Protection against client providing incorrect data
    var catalog = server.GetCatalogItems({ CatalogVersion: itemInstance.CatalogVersion });
    var catalogItem = null;
    for (var c = 0; c < catalog.Catalog.length; c++) {
        if (itemInstance.ItemId === catalog.Catalog[c].ItemId)
            catalogItem = catalog.Catalog[c];
    }
    if (!catalogItem)
        throw "Catalog Item not found"; // Title catalog consistency check (You should never remove a catalog/catalogItem if any player owns that item
    var buyPrice = 0;
    if (catalogItem.VirtualCurrencyPrices.hasOwnProperty(requestedVcType))
        buyPrice = catalogItem.VirtualCurrencyPrices[requestedVcType];
    if (buyPrice <= 0)
        throw "Cannot redeem this item for: " + requestedVcType; // The client requested a virtual currency which doesn't apply to this item
    // Once we get here all safety checks are passed - Perform the sell
    var sellPrice = Math.floor(buyPrice * SELL_PRICE_RATIO);
    server.AddUserVirtualCurrency({ PlayFabId: currentPlayerId, Amount: sellPrice, VirtualCurrency: requestedVcType });
    server.RevokeInventoryItem({ PlayFabId: currentPlayerId, ItemInstanceId: soldItemInstanceId });
}

handlers.SellItem = function (args) {
    if (!args || !args.soldItemInstanceId || !args.requestedVcType)
        throw "Invalid input parameters, expected soldItemInstanceId and requestedVcType";
    SellItem_internal(args.soldItemInstanceId, args.requestedVcType);
};

Bewährte Methoden

  • Vergewissern Sie sich, dass alle Client-Eingabeinformationen gültig sind, bevor Sie Änderungen vornehmen.

  • CloudScript ist nicht atomar, daher ist die Aufrufreihenfolge wichtig: AddUserVirtualCurrency kann erfolgreich sein, und RevokeInventoryItem schlägt möglicherweise fehl.

Tipp

Im Allgemeinen ist es besser, dem Spieler etwas zu geben, das er in diesem Prozess nicht verdient hat, als etwas wegzunehmen, ohne ihm im Gegenzug etwas anderes zu bieten.

Auf diese CloudScript-Funktion kann dann vom Client aus zugegriffen werden.

void SellItem()
{
    PlayFabClientAPI.ExecuteCloudScript(new ExecuteCloudScriptRequest
    {
        // This must match "SellItem" from the "handlers.SellItem = ..." line in the CloudScript file
        FunctionName = "SellItem",
        FunctionParameter = new Dictionary<string, string>{
            // This is a hex-string value from the GetUserInventory result
            { "soldItemInstanceId", "sellItemInstanceId" },
            // Which redeemable virtual currency should be used in your game
            { "requestedVcType", "AU" },
        }
    }, LogSuccess, LogFailure);
}