Exemples d'utilisation de l'API produit
Les exemples suivants montrent comment utiliser l'API Produit pour gérer la Monnaie Mondiale et les Produits Mondiaux.
Cet exemple vous permet de comprendre les bases de l'API Produit et d'implémenter l'envoi et la réception de messages entre le serveur et le client, afin que vous puissiez facilement tester l'octroi et la déduction de monnaies et de produits mondiaux.
Cet exemple comprend des descriptions des scripts clients de la Monnaie Mondiale et des Produits Mondiaux, suivies du script serveur intégré qui gère tout le traitement côté serveur, et inclut les fonctions suivantes :
- Octroi de Monnaie Mondiale
- Déduction de Monnaie Mondiale
- Octroi de Produits Mondiaux sans Déduction de Monnaie
- Déduction de Produits Mondiaux

Octroi & Déduction de Monnaie Mondiale
Ci-dessous se trouve le code client complet pour gérer l'octroi et la déduction de devises mondiales, et comment l'implémenter.
Script Client de Devises
import { Button, Text } from 'UnityEngine.UI';
import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
import { LocalPlayer, ZepetoPlayers } from 'ZEPETO.Character.Controller';
import { Room, RoomData } from 'ZEPETO.Multiplay';
import { ZepetoWorldMultiplay } from 'ZEPETO.World';
export default class CurrencyManagerSample extends ZepetoScriptBehaviour {
public currencyId: string;
public increaseQuantity: number;
public decreaseQuantity: number;
public increaseCurrencyBtn: Button;
public decreaseCurrencyBtn: Button;
public balanceText: Text;
public multiplay: ZepetoWorldMultiplay;
private _localPlayer: LocalPlayer;
Start() {
ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
this._localPlayer = ZepetoPlayers.instance.LocalPlayer;
this.loadCurrencyBalance(this.currencyId);
});
// Gère les événements de salle rejointes pour les mises à jour de l'UI de la devise
this.multiplay.RoomJoined += (room: Room) => {
room.AddMessageHandler("SyncCurrencyInfo", (message: CurrencyMessage) => {
const currentCurrencyId = message.currencyId;
const currentQuantity = message.quantity;
this.balanceUIUpdate(currentCurrencyId, currentQuantity);
});
};
// Écouteur d'événements de bouton pour augmenter la devise : Demander un Crédit
this.increaseCurrencyBtn.onClick.AddListener(() => {
const data = new RoomData();
data.Add("currencyId", this.currencyId);
data.Add("quantity", this.increaseQuantity);
this.multiplay.Room?.Send("CreditCurrency", data.GetObject());
})
// Écouteur d'événements de bouton pour diminuer la devise : Demander un Débit
this.decreaseCurrencyBtn.onClick.AddListener(() => {
const data = new RoomData();
data.Add("currencyId", this.currencyId);
data.Add("quantity", this.decreaseQuantity);
this.multiplay.Room?.Send("DebitCurrency", data.GetObject());
})
}
// Demande le montant actuel de la devise spécifiée
private loadCurrencyBalance(currentCurrencyId: string) {
this.multiplay.Room?.Send("LoadBalance", currentCurrencyId);
}
// Met à jour l'UI pour refléter la quantité actuelle de la devise
private balanceUIUpdate(currentCurrencyId: string, currentQuantity: number) {
this.balanceText.text = currentQuantity.toString();
}
}
// Interface pour les messages de synchronisation de devise
interface CurrencyMessage {
currencyId: string,
quantity: number,
}
Description du Script Client de Devises
- Lorsqu'un personnage est chargé, un message de salle est envoyé au serveur pour charger le solde existant de la devise. L'UI est ensuite mise à jour en fonction des informations de solde reçues du serveur.
this.multiplay.Room?.Send("LoadBalance", currentCurrencyId);- Pour faciliter l'échange de messages, l'CurrencyMessage interface est définie.
interface CurrencyMessage {
currencyId: string,
quantity: number,
}- Lorsqu'un utilisateur augmente ou diminue sa monnaie, il envoie une demande au serveur sous forme de message de salle. Cela inclut des données sur quelle monnaie augmenter ou diminuer et de combien.
this.multiplay.Room?.Send("CreditCurrency", data.GetObject());
this.multiplay.Room?.Send("DebitCurrency", data.GetObject());- Le serveur traite ensuite l'augmentation ou la diminution de la monnaie et envoie les informations de solde final au client. Le client reçoit ces informations et met à jour l'interface utilisateur.
this.multiplay.RoomJoined += (room: Room) => {
room.AddMessageHandler("SyncCurrencyInfo", (message: CurrencyMessage) => {
const currentCurrencyId = message.currencyId;
const currentQuantity = message.quantity;
this.updateBalanceUI(currentCurrencyId, currentQuantity);
});
};
Accorder & Déduire des Produits Mondiaux
Ci-dessous se trouve le code client complet pour gérer l'octroi et la déduction de produits mondiaux, et comment l'implémenter.
Script Client Produit
import { Button, Text } from 'UnityEngine.UI';
import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
import { LocalPlayer, ZepetoPlayers } from 'ZEPETO.Character.Controller';
import { Room, RoomData } from 'ZEPETO.Multiplay';
import { ZepetoWorldMultiplay } from 'ZEPETO.World';
import { InventoryRecord, InventoryService } from 'ZEPETO.Inventory';
import { WaitUntil } from 'UnityEngine';
export default class ProductManagerSample extends ZepetoScriptBehaviour {
public productId: string;
public productAddQuantity: number;
public acquireItemBtn: Button;
public useItemBtn: Button;
public itemCountText: Text;
public multiplay: ZepetoWorldMultiplay;
private _localPlayer: LocalPlayer;
Start() {
ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
this._localPlayer = ZepetoPlayers.instance.LocalPlayer;
this.StartCoroutine(this.refreshProductUI());
});
// Gère les événements de salle rejointes pour les mises à jour de l'UI produit
this.multiplay.RoomJoined += (room: Room) => {
room.AddMessageHandler("SyncProductInfo", (message: ProductMessage) => {
this.StartCoroutine(this.refreshProductUI());
});
};
// Écouteur d'événements de bouton pour l'acquisition d'éléments : Ajouter Produit
this.acquireItemBtn.onClick.AddListener(() => {
const data = new RoomData();
data.Add("productId", this.productId);
data.Add("quantity", this.productAddQuantity);
this.multiplay.Room?.Send("AddProduct", data.GetObject());
})
// Écouteur d'événements de bouton pour l'utilisation d'éléments : Utiliser Produit
this.useItemBtn.onClick.AddListener(() => {
const data = new RoomData();
data.Add("productId", this.productId);
data.Add("quantity", 1);
this.multiplay.Room?.Send("UseProduct", data.GetObject());
})
}
private * refreshProductUI() {
const request = InventoryService.GetAsync(this.productId);
yield new WaitUntil(() => request.keepWaiting == false);
// Si la demande est réussie, met à jour l'UI Produit
if (request.responseData.isSuccess) {
this.updateItemCountText(request.responseData.product);
}
else {
console.log("Échec du chargement de l'élément produit.");
}
}
private updateItemCountText(item: InventoryRecord) {
if (item != null) {
this.itemCountText.text = item.quantity.toString();
}
else {
this.itemCountText.text = "0";
}
}
}
// Interface pour les messages de produit.
interface ProductMessage {
productId: string,
productAction: ProductAction,
}
// Enum pour définir les types d'actions de produit.
export enum ProductAction {
Utiliser,
Ajouter,
}
Description du script client du produit
- Lorsqu'un personnage se charge, utilisez le InventoryService de ZEPETO.Inventory pour charger l'inventaire initial des produits. Ensuite, mettez à jour l'interface utilisateur.
private * refreshProductUI() {
const request = InventoryService.GetAsync(this.productId);
yield new WaitUntil(() => request.keepWaiting == false);
if (request.responseData.isSuccess) {
this.updateItemCountText(request.responseData.product);
}
else {
console.log("Échec du chargement de l'élément produit.");
}
}- Pour envoyer et recevoir des messages, définissez l'ProductMessage interface. Définissez un ProductAction Enum pour l'implémentation d'exemple.
interface ProductMessage {
productId: string,
productAction: ProductAction,
}
export enum ProductAction {
Utiliser,
Ajouter,
}- Lorsque vous augmentez ou diminuez un produit, vous envoyez ces données au serveur en tant que message de salle. Cela inclut des données sur quel produit augmenter ou diminuer et de combien.
this.multiplay.Room?.Send("AddProduct", data.GetObject());
this.multiplay.Room?.Send("UseProduct", data.GetObject());- Après avoir traité les changements de produit, le serveur envoie les informations finales sur l'inventaire au client, qui met à jour l'interface utilisateur en conséquence.
this.multiplay.RoomJoined += (room: Room) => {
room.AddMessageHandler("SyncProductInfo", (message: ProductMessage) => {
this.StartCoroutine(this.refreshProductUI());
});
};- En général, les produits du monde devraient coûter de la monnaie pour être achetés.
- Dans ce cas, vous pouvez facilement les vendre avec un Bouton d'Achat de Produit en vous référant au guide Monétisez votre monde ! Configuration des produits et des devises
Script de serveur
Voici le code complet du serveur qui gère la monnaie mondiale et les produits, et comment l'implémenter.
Script de serveur complet
import { Sandbox, SandboxOptions, SandboxPlayer } from "ZEPETO.Multiplay";
import { loadCurrency } from "ZEPETO.Multiplay.Currency";
import { loadInventory } from "ZEPETO.Multiplay.Inventory";
export default class extends Sandbox {
async onCreate(options: SandboxOptions) {
// Monnaie
//Demande de chargement de la monnaie
this.onMessage("LoadBalance", (client, message: string) => {
this.loadBalance(client, message);
});
//Demande d'ajout de crédit
this.onMessage("CreditCurrency", (client, message: CurrencyMessage ) => {
const currencyId = message.currencyId;
const quantity = message.quantity;
this.addCredit(client, currencyId, quantity);
});
//Demande de débit de crédit
this.onMessage("DebitCurrency", (client, message: CurrencyMessage ) => {
const currencyId = message.currencyId;
const quantity = message.quantity;
this.onDebit(client, currencyId, quantity);
});
// Produit
//Demande d'ajout d'article
this.onMessage("AddProduct", (client, message: any) => {
const productId = message.productId;
const quantity = message.quantity;
this.addProduct(client, productId, quantity);
});
//Demande d'utilisation d'article
this.onMessage("UseProduct", (client, message: any) => {
const productId = message.productId;
const quantity = message.quantity;
this.useProduct(client, productId, quantity);
});
}
async addCredit(client: SandboxPlayer, currencyId: string, quantity: number) {
try {
const currency = await loadCurrency(client.userId);
await currency.credit(currencyId, quantity);
this.loadBalance(client, currencyId);
} catch (e) {
console.error(`AddCredit Error: ${e}`);
}
}
async onDebit(client: SandboxPlayer, currencyId: string, quantity: number) {
try {
const currency = await loadCurrency(client.userId);
if (await currency.debit(currencyId, quantity) === true) {
this.loadBalance(client, currencyId);
} else {
console.error("DebitCredit Error: Monnaie Insuffisante");
}
} catch (e) {
console.error(`DebitCredit Error: ${e}`);
}
}
async loadBalance(client: SandboxPlayer, currencyId: string) {
try {
const currency = await loadCurrency(client.userId);
let balancesObject = await currency.getBalances();
let balancesMap: Map<string, number> = new Map(Object.entries(balancesObject));
const specificCurrencyID = currencyId;
const specificBalance = balancesMap.get(specificCurrencyID) ?? 0;
const currencySync: CurrencyMessage = {
currencyId: specificCurrencyID,
quantity: specificBalance
}
client.send("SyncCurrencyInfo", currencySync);
} catch (e) {
console.error(`loadBalance Error: ${e}`);
}
}
async addProduct(client: SandboxPlayer, productId: string, quantity: number) {
try {
const inventory = await loadInventory(client.userId);
await inventory.add(productId, quantity);
const productMessage: ProductMessage = {
productId: productId,
productAction: ProductAction.Add
}
client.send("SyncProductInfo", productMessage);
} catch (e) {
console.error(`addProduct Error: ${e}`);
}
}
async useProduct(client: SandboxPlayer, productId: string, quantity: number) {
try {
const inventory = await loadInventory(client.userId);
await inventory.use(productId, quantity);
const productMessage: ProductMessage = {
productId: productId,
productAction: ProductAction.Use
}
client.send("SyncProductInfo", productMessage);
} catch (e) {
console.error(`useProduct Error: ${e}`);
}
}
onJoin(client: SandboxPlayer) {
// Logique OnJoin ici
}
onTick(deltaTime: number): void {
// Logique Tick ici
}
onLeave(client: SandboxPlayer, consented?: boolean) {
// Gérer la logique de départ ici
}
}
// Interface pour les messages de monnaie
interface CurrencyMessage {
currencyId: string,
quantity: number,
}
// Interface pour les messages de produit.
interface ProductMessage {
productId: string,
productAction: ProductAction,
}
// Enum pour définir les types d'actions de produit.
export enum ProductAction {
Use,
Add,
}
Description du script serveur
- Utiliser currency.credit() et currency.debit() pour augmenter ou diminuer le solde de la monnaie souhaitée. Ensuite, appelez currency.getBalances() pour obtenir le solde actuel de chaque monnaie.
currency.credit(currencyId, quantity);
currency.debit(currencyId, quantity);
currency.getBalances();- Utiliser inventory.add() et inventory.use() pour augmenter ou diminuer le solde de la monnaie souhaitée.
inventory.add(productId, quantity);
inventory.use(productId, quantity);- Gère les demandes des clients pour augmenter ou diminuer les devises et les produits.
- Utilisez loadBalance() pour obtenir les informations de devise enregistrées dans ZEPETO Studio.
- S'il y a plusieurs devises, vous pouvez conditionner sur une valeur d'ID de devise spécifique pour obtenir le solde de cette seule devise.
- Passez la valeur finale du solde au client en tant que message de salle.