Guide de création de joueurs bot
Les joueurs bots sont utilisés pour combler les vides lorsqu'il n'y a pas assez de personnes pour commencer un monde multijoueur, ou lorsqu'un joueur quitte pendant un monde.
Le comportement du joueur bot doit être implémenté pour chaque contenu.
Ce guide décrit la méthode générale de création d'un joueur bot.
📘 Le guide de création du joueur Bot est basé sur le guide multijoueur. [Tutoriel Multijoueur]
ÉTAPE 1 : Créer un Joueur Bot
1-1. Ajoutez une valeur booléenne appelée IsBot au schéma multijoueur.

1-2. Définissez la fonction ci-dessous pour créer un joueur bot dans le script serveur index.ts et appelez-la au point désiré.
// La méthode `CreateBot()` est utilisée pour créer un joueur bot avec le `userId` donné.
CreateBot(userId: string) {
// Générer un ID de session pour le joueur bot en utilisant le `userId` fourni.
const sessionId = "Bot_" + userId;
// Vérifier si un joueur bot avec le même ID de session existe déjà. Si c'est le cas, retourner sans créer de doublon.
if (this.state.players.has(sessionId)) {
return;
}
// Créer un nouvel objet `Player` pour le joueur bot.
const player: Player = new Player();
player.sessionId = sessionId;
if (userId) {
player.zepetoUserId = userId;
}
player.isBot = true;
// Ajouter le joueur bot à la carte des joueurs de l'état en utilisant l'ID de session comme clé.
this.state.players.set(player.sessionId, player);
this._botMap.set(sessionId, player);
}
👍 Conseils
- L'userId d'un utilisateur spécifique est stocké à l'avance pour que le personnage bot soit créé.
- Vous pouvez vérifier l'UserId d'un utilisateur spécifique en vérifiant l'userId du client se connectant à OnJoin sur le serveur. Après avoir écrit le script ci-dessous dans le script du serveur, connectez-vous depuis le monde concerné.
onJoin(client: SandboxPlayer) {
console.log(client.userId);
}
ÉTAPE 2 : Créer un joueur Bot sur le client
2-1. Si vous avez le serveur qui crée un joueur Bot à un moment donné, le client le reconnaîtra comme un nouveau joueur dans OnJoinPlayer().
- Créer un projet > Créer > ZEPETO > TypeScript et le renommer en BotPlayerManager.
- Ajouter une logique dans OnAddedPlayer() pour créer chaque joueur, et ajouter une logique pour distinguer les joueurs bots et créer leurs personnages ZEPETO.
import { ZepetoCharacter, ZepetoPlayers } from 'ZEPETO.Character.Controller';
import { Room } from 'ZEPETO.Multiplay';
import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
import { ZepetoWorldMultiplay } from 'ZEPETO.World';
export default class BotPlayerManager extends ZepetoScriptBehaviour {
public zepetoWorldMultiplay: ZepetoWorldMultiplay;
// Variables privées pour stocker la salle actuelle et les données du joueur bot.
private _room: Room;
private _botMapData: Map<string, ZepetoCharacter> = new Map<string, ZepetoCharacter>();
Start() {
// Écouter l'événement `RoomJoined` du composant `ZepetoWorldMultiplay`.
this.zepetoWorldMultiplay.RoomJoined += (room: Room) => {
this._room = room;
}
// Écouter l'événement `OnAddedPlayer` de `ZepetoPlayers.instance` pour gérer les joueurs nouvellement ajoutés.
ZepetoPlayers.instance.OnAddedPlayer.AddListener((userId: string) => {
// Obtenir les données du joueur actuel à partir de l'état de la salle en utilisant le `userId`.
const currentPlayer = this._room.State.players.get_Item(userId);
// Vérifier si le joueur est un bot, et si c'est le cas, le définir comme un joueur bot.
if (currentPlayer.isBot) {
this.SetBotPlayer(currentPlayer.sessionId);
}
});
}
}
2-2. Écrivez la fonction SetBotPlayer pour ajouter des balises et des composants de synchronisation aux joueurs bots et créer des scripts pour les contrôler.
- Définissez _botMapData pour enregistrer les données des joueurs bots au format Map afin de gérer les joueurs bots.
// La méthode `SetBotPlayer()` est utilisée pour définir un joueur comme un bot.
SetBotPlayer(userId: string) {
// Obtenez le personnage ZEPETO associé au joueur bot en utilisant son `userId`.
const bot = ZepetoPlayers.instance.GetPlayer(userId).character;
// Définissez le nom du personnage sur le `userId` pour identification.
bot.gameObject.name = userId;
// Stockez les données du joueur bot dans la carte `_botMapData` en utilisant son `userId` comme clé.
this._botMapData.set(userId, bot);
}
👍 Conseils Vous pouvez ajouter des scripts ou des paramètres supplémentaires à SetBotPlayer() pour contrôler le comportement des joueurs bots.
ÉTAPE 3 : Créez un bouton de joueur bot sur le client
Pour les mondes qui nécessitent un certain nombre de joueurs pour commencer, il arrive parfois qu'il n'y ait pas assez de joueurs et que vous deviez attendre longtemps que le monde commence.
Dans ce cas, vous pouvez commencer le monde en ajoutant un joueur Bot.
3-1. Enregistrez une fonction pour exécuter CreateBot() lorsque le serveur reçoit un message du client dans index.ts.
async OnCreate() {
// Gérer le message "CreateBot", qui crée un joueur bot avec l'userId donné.
this.onMessage("CreateBot", (client, message) => {
this.CreateBot(message);
});
}
3-2. Dans le script client BotPlayerManager.ts, écrivez une fonction pour envoyer le message "CreateBot" au serveur.
- La façon d'exécuter une fonction est d'envoyer un message en appuyant sur un bouton.
- Envoyez l'ID utilisateur du joueur Bot à créer sous forme de chaîne à travers le message.
public buttonCreateBot: Button;
public botPlayerId: string;
Start() {
// Ajouter un écouteur de clic au bouton "Create Bot" pour envoyer un message pour créer un joueur bot.
this.buttonCreateBot.onClick.AddListener(() => {
this._room.Send("CreateBot", this.botPlayerId);
});
}
3-3. Maintenant, lorsque vous exécutez le serveur et le runtime, vous pouvez voir que des joueurs bots sont créés lorsque vous appuyez sur le bouton.

ÉTAPE 4 : Démarrez le monde en ajoutant un joueur bot
Lorsqu'il n'y a pas assez de joueurs pour démarrer le monde, vous pouvez ajouter des joueurs bots pour initier le monde.
4-1. Dans le script du serveur, ajoutez le code suivant lors de OnJoin pour vérifier le nombre de joueurs et commencer le monde lorsqu'il y a au moins quatre joueurs.
- Ajoutez une fonction pour vérifier le nombre de joueurs dans CreateBot().
- Ajoutez un compteur pour le nombre de jeux dans la fonction StartWorld().
async onJoin(client: SandboxPlayer) {
// Vérifiez le nombre de joueurs dans la salle après qu'un joueur se soit joint.
this.CheckPlayerNumber();
}
// La méthode `CheckPlayerNumber()` vérifie le nombre de joueurs dans la salle et commence le monde s'il y a au moins quatre joueurs.
CheckPlayerNumber() {
// Imprimez le nombre actuel de joueurs dans la salle dans la console.
console.log(`nombre de joueurs, ${this.state.players.size}`);
// S'il y a au moins quatre joueurs dans la salle, commencez le monde.
if (this.state.players.size >= 4) {
this.StartWorld();
}
}
// La méthode `CreateBot()` est utilisée pour créer un joueur bot avec le `userId` donné.
CreateBot(userId: string) {
// Générez un ID de session pour le joueur bot en utilisant le `userId` fourni.
const sessionId = "Bot_" + userId;
// Vérifiez si un joueur bot avec le même ID de session existe déjà. Si oui, retournez sans créer de doublon.
if (this.state.players.has(sessionId)) {
return;
}
// Créez un nouvel objet `Player` pour le joueur bot.
const player: Player = new Player();
player.sessionId = sessionId;
if (userId) {
player.zepetoUserId = userId;
}
player.isBot = true;
// Ajoutez le joueur bot à la carte des joueurs de l'état en utilisant l'ID de session comme clé.
this.state.players.set(player.sessionId, player);
this._botMap.set(sessionId, player);
// Vérifiez le nombre de joueurs dans la salle après avoir ajouté le joueur bot.
this.CheckPlayerNumber();
}
private playTime: number = 0;
// La méthode `StartWorld()` incrémente le temps de jeu et diffuse le message "StartWorld" à tous les clients.
StartWorld() {
this.playTime += 1;
// Imprimez un message indiquant le début du monde et le temps de jeu actuel.
console.log("Démarrer le monde !");
this.broadcast("StartWorld", this.playTime);
}
- Sur le serveur, OnJoin est exécuté lorsqu'un vrai joueur rejoint la salle. Donc, lorsqu'un joueur Bot est créé via CreateBot et qu'un joueur entre via OnJoin, checkPlayerNumber() ajoute le nombre de personnes.
4-2. Dans le script client, BotPlayerManager.ts, écrivez StartWorld(), qui est exécuté lorsque le message StartWorld est reçu du serveur.
Start() {
// Écoutez l'événement `RoomJoined` du composant `ZepetoWorldMultiplay`.
this.zepetoWorldMultiplay.RoomJoined += (room: Room) => {
// Ajoutez un gestionnaire de message pour le type de message "StartWorld".
this._room.AddMessageHandler("StartWorld", (playTime: number) => {
this.StartWorld(playTime);
});
}
// La méthode `StartWorld()` est appelée lorsque le monde commence avec le `playTime` fourni.
StartWorld(playTime: number) {
// Imprimez le message de début du monde avec le `playTime`.
console.log(`Démarrer le monde : ${playTime}`);
}
4-3. Au moment de l'exécution, lorsqu'il y a plus de 4 joueurs, y compris des joueurs Bot, vous pouvez voir un journal appelé Démarrer le monde apparaître sur la console du serveur et sur la console du client.

ÉTAPE 5 : Synchroniser la position du joueur Bot
Ci-dessous un exemple de code qui déplace les joueurs Bot ajoutés à la position du joueur local et synchronise la position de mouvement.
5-1. Tout d'abord, écrivez le code pour déplacer les joueurs Bot lorsque le message MoveBot est reçu du client dans index.ts du serveur.
async OnCreate() {
// Gérer le message "MoveBot", qui déplace le joueur bot à la position spécifiée.
this.onMessage("MoveBot", (client, message) => {
this.MoveBot(client, message);
});
}
// La méthode `MoveBot()` déplace le joueur bot à la position spécifiée en fonction du message reçu.
MoveBot(client: SandboxPlayer, message: string) {
// Analyser le message JSON reçu du client pour extraire les informations de position.
const position = JSON.parse(message);
// Créer un nouvel objet message avec l'ID de session de l'utilisateur et les données de position analysées.
const newMessage = {
user: client.sessionId,
positionX: position.x,
positionY: position.y,
positionZ: position.z
}
// Diffuser le message "MoveBotToPosition" à tous les clients avec les nouvelles données de message sous forme de chaîne JSON.
this.broadcast("MoveBotToPosition", JSON.stringify(newMessage));
}
5-2. Dans le script client, BotPlayerManager.ts, écrivez SendBotPosition() qui envoie la position du joueur local au serveur lorsque buttonCallBot est pressé.
- Ensuite, écrivez du code pour déplacer tous les joueurs Bot vers les informations de localisation incluses dans le message lorsque le message MoveBotToPosition est reçu du serveur.
public buttonCallBot: Button;
Start(){
// Écoutez l'événement `RoomJoined` du composant `ZepetoWorldMultiplay`.
this.zepetoWorldMultiplay.RoomJoined += (room: Room) => {
this._room = room;
// Ajoutez un gestionnaire de message pour le type de message "StartWorld".
this._room.AddMessageHandler("StartWorld", (playTime: number) => {
this.StartWorld(playTime);
});
// Ajoutez un écouteur de clic au bouton "Call Bot" pour envoyer un message pour envoyer la position d'un joueur bot.
this.buttonCallBot.onClick.AddListener(() => {
this.SendBotPosition();
});
}
// Cette méthode envoie la position du personnage du joueur local au serveur pour la synchronisation du mouvement des bots.
SendBotPosition() {
// Obtenez la position du personnage du joueur local.
const localPlayerPosition = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character.transform.position;
// Créez un objet de position contenant les coordonnées x, y et z du personnage du joueur local.
const position = {
x: localPlayerPosition.x,
y: localPlayerPosition.y,
z: localPlayerPosition.z
}
// Convertissez l'objet de position en chaîne JSON et envoyez-le au serveur avec le type de message "MoveBot".
this._room.Send("MoveBot", JSON.stringify(position));
}
MoveBotToPosition(message) {
// Analysez le message JSON reçu du client pour extraire les informations de position.
const jsonMessage = JSON.parse(message);
const position = new Vector3(jsonMessage.positionX, jsonMessage.positionY, jsonMessage.positionZ);
// Déplacez chaque personnage bot dans la carte `_botMapData` vers la position spécifiée avec un petit décalage aléatoire sur les axes x et z.
this._botMapData.forEach((character: ZepetoCharacter) => {
// La méthode `MoveToPosition()` est utilisée pour déplacer le personnage vers la position spécifiée.
// Ici, un petit décalage aléatoire est ajouté à la position cible pour créer un mouvement naturel pour les bots.
character.MoveToPosition(position + new Vector3(Random.Range(0.5, 1), 0, Random.Range(0.5, 1)));
});
}
5-3. Maintenant, si vous créez un joueur Bot à l'exécution et appuyez sur le bouton buttonCallBot, vous devriez voir le joueur Bot créé se déplacer vers la position du personnage du joueur local.

Code complet de BotPlayerManager.ts
import { Random, Vector3 } from 'UnityEngine';
import { Button } from 'UnityEngine.UI';
import { ZepetoCharacter, ZepetoPlayers } from 'ZEPETO.Character.Controller';
import { Room } from 'ZEPETO.Multiplay';
import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
import { ZepetoWorldMultiplay } from 'ZEPETO.World';
export default class BotPlayerManager extends ZepetoScriptBehaviour {
// Propriétés publiques pour référencer les composants et paramètres nécessaires depuis l'Inspecteur.
public zepetoWorldMultiplay: ZepetoWorldMultiplay;
public buttonCreateBot: Button;
public buttonCallBot: Button;
public botPlayerId: string;
// Variables privées pour stocker la salle actuelle et les données du joueur bot.
private _room: Room;
private _botMapData: Map<string, ZepetoCharacter> = new Map<string, ZepetoCharacter>();
Start() {
// Écoutez l'événement `RoomJoined` du composant `ZepetoWorldMultiplay`.
this.zepetoWorldMultiplay.RoomJoined += (room: Room) => {
this._room = room;
// Ajoutez un gestionnaire de message pour le type de message "StartWorld".
this._room.AddMessageHandler("StartWorld", (playTime: number) => {
this.StartWorld(playTime);
});
}
// Écoutez l'événement `OnAddedPlayer` de `ZepetoPlayers.instance` pour gérer les joueurs nouvellement ajoutés.
ZepetoPlayers.instance.OnAddedPlayer.AddListener((userId: string) => {
// Obtenez les données du joueur actuel à partir de l'état de la salle en utilisant le `userId`.
const currentPlayer = this._room.State.players.get_Item(userId);
// Vérifiez si le joueur est un bot, et si oui, définissez-le comme un joueur bot.
if (currentPlayer.isBot) {
this.SetBotPlayer(currentPlayer.sessionId);
}
});
// Ajoutez un écouteur de clic au bouton "Créer Bot" pour envoyer un message pour créer un joueur bot.
this.buttonCreateBot.onClick.AddListener(() => {
this._room.Send("CreateBot", this.botPlayerId);
});
this.zepetoWorldMultiplay.RoomJoined += (room: Room) => {
this._room = room;
this._room.AddMessageHandler("MoveBotToPosition", (message: string) => {
this.MoveBotToPosition(message);
});
}
// Ajoutez un écouteur de clic au bouton "Appeler Bot" pour envoyer un message pour envoyer la position d'un joueur bot.
this.buttonCallBot.onClick.AddListener(() => {
this.SendBotPosition();
});
}
// La méthode `SetBotPlayer()` est utilisée pour définir un joueur comme un bot.
SetBotPlayer(userId: string) {
// Obtenez le personnage ZEPETO associé au joueur bot en utilisant leur `userId`.
const bot = ZepetoPlayers.instance.GetPlayer(userId).character;
// Définissez le nom du personnage sur le `userId` pour identification.
bot.gameObject.name = userId;
// Stockez les données du joueur bot dans la carte `_botMapData` en utilisant leur `userId` comme clé.
this._botMapData.set(userId, bot);
}
// La méthode `StartWorld()` est appelée lorsque le monde commence avec le `playTime` fourni.
StartWorld(playTime: number) {
// Imprimez le message de début du monde avec le `playTime`.
console.log(`Début du Monde : ${playTime}`);
}
// Cette méthode envoie la position du personnage du joueur local au serveur pour la synchronisation du mouvement du bot.
SendBotPosition() {
// Obtenez la position du personnage du joueur local.
const localPlayerPosition = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character.transform.position;
// Créez un objet de position contenant les coordonnées x, y et z du personnage du joueur local.
const position = {
x: localPlayerPosition.x,
y: localPlayerPosition.y,
z: localPlayerPosition.z
}
// Convertissez l'objet de position en chaîne JSON et envoyez-le au serveur avec le type de message "MoveBot".
this._room.Send("MoveBot", JSON.stringify(position));
}
// Cette méthode est appelée lorsque le serveur reçoit le message "MoveBot" d'un client et déplace les personnages bots à la position spécifiée.
MoveBotToPosition(message) {
// Analysez le message JSON reçu du client pour extraire les informations de position.
const jsonMessage = JSON.parse(message);
const position = new Vector3(jsonMessage.positionX, jsonMessage.positionY, jsonMessage.positionZ);
// Déplacez chaque personnage bot dans la carte `_botMapData` à la position spécifiée avec un petit décalage aléatoire sur les axes x et z.
this._botMapData.forEach((character: ZepetoCharacter) => {
// La méthode `MoveToPosition()` est utilisée pour déplacer le personnage à la position spécifiée.
// Ici, un petit décalage aléatoire est ajouté à la position cible pour créer un mouvement naturel pour les bots.
character.MoveToPosition(position + new Vector3(Random.Range(0.5, 1), 0, Random.Range(0.5, 1)));
});
}
}
code complet du serveur index.ts
import { Sandbox, SandboxOptions, SandboxPlayer } from "ZEPETO.Multiplay";
import { DataStorage } from "ZEPETO.Multiplay.DataStorage";
import { Player, Transform, Vector3 } from "ZEPETO.Multiplay.Schema";
export default class extends Sandbox {
storageMap: Map<string, DataStorage> = new Map<string, DataStorage>();
// Enregistrer les données de la carte du joueur bot comme _botMap
private _botMap: Map<string, Player> = new Map<string, Player>();
private playTime: number = 0;
constructor() {
super();
}
onCreate(options: SandboxOptions) {
// Appelé lorsque l'objet Room est créé.
// Gérer l'état ou l'initialisation des données de l'objet Room.
this.onMessage("onChangedTransform", (client, message) => {
this.state.players.get(client.sessionId);
const player = this.state.players.get(client.sessionId);
const transform = new Transform();
transform.position = new Vector3();
transform.position.x = message.position.x;
transform.position.y = message.position.y;
transform.position.z = message.position.z;
transform.rotation = new Vector3();
transform.rotation.x = message.rotation.x;
transform.rotation.y = message.rotation.y;
transform.rotation.z = message.rotation.z;
if (player) {
player.transform = transform;
}
});
this.onMessage("onChangedState", (client, message) => {
const player = this.state.players.get(client.sessionId);
if (player) {
player.state = message.state;
player.subState = message.subState;
}
});
// Gérer le message "CreateBot", qui crée un joueur bot avec l'ID utilisateur donné.
this.onMessage("CreateBot", (client, message) => {
this.CreateBot(message);
});
// Gérer le message "MoveBot", qui déplace le joueur bot à la position spécifiée.
this.onMessage("MoveBot", (client, message) => {
this.MoveBot(client, message);
});
}
// La méthode `CreateBot()` est utilisée pour créer un joueur bot avec le `userId` donné.
CreateBot(userId: string) {
// Générer un ID de session pour le joueur bot en utilisant le `userId` fourni.
const sessionId = "Bot_" + userId;
// Vérifier si un joueur bot avec le même ID de session existe déjà. Si oui, retourner sans créer de doublon.
if (this.state.players.has(sessionId)) {
return;
}
// Créer un nouvel objet `Player` pour le joueur bot.
const player: Player = new Player();
player.sessionId = sessionId;
if (userId) {
player.zepetoUserId = userId;
}
player.isBot = true;
// Ajouter le joueur bot à la carte des joueurs de l'état en utilisant l'ID de session comme clé.
this.state.players.set(player.sessionId, player);
this._botMap.set(sessionId, player);
// Vérifier le nombre de joueurs dans la salle après avoir ajouté le joueur bot.
this.CheckPlayerNumber();
}
// La méthode `CheckPlayerNumber()` vérifie le nombre de joueurs dans la salle et démarre le monde s'il y a au moins quatre joueurs.
CheckPlayerNumber() {
// Imprimer le nombre actuel de joueurs dans la salle dans la console.
console.log(`nombre de joueurs, ${this.state.players.size}`);
// S'il y a au moins quatre joueurs dans la salle, démarrer le monde.
if (this.state.players.size >= 4) {
this.StartWorld();
}
}
// La méthode `StartWorld()` incrémente le temps de jeu et diffuse le message "StartWorld" à tous les clients.
StartWorld() {
this.playTime += 1;
// Imprimer un message indiquant le début du monde et le temps de jeu actuel.
console.log("Démarrer le monde !");
this.broadcast("StartWorld", this.playTime);
}
// La méthode `MoveBot()` déplace le joueur bot à la position spécifiée en fonction du message reçu.
MoveBot(client: SandboxPlayer, message: string) {
// Analyser le message JSON reçu du client pour extraire les informations de position.
const position = JSON.parse(message);
// Créer un nouvel objet message avec l'ID de session de l'utilisateur et les données de position analysées.
const newMessage = {
user: client.sessionId,
positionX: position.x,
positionY: position.y,
positionZ: position.z
}
// Diffuser le message "MoveBotToPosition" à tous les clients avec les nouvelles données de message sous forme de chaîne JSON.
this.broadcast("MoveBotToPosition", JSON.stringify(newMessage));
}
async onJoin(client: SandboxPlayer) {
// Créer l'objet joueur défini dans schemas.json et définir la valeur initiale.
console.log(`[OnJoin] sessionId : ${client.sessionId}, HashCode : ${client.hashCode}, userId : ${client.userId}`)
const player = new Player();
player.sessionId = client.sessionId;
if (client.hashCode) {
player.zepetoHash = client.hashCode;
}
if (client.userId) {
player.zepetoUserId = client.userId;
}
// [DataStorage] Chargement de DataStorage du joueur entré
const storage: DataStorage = client.loadDataStorage();
this.storageMap.set(client.sessionId, storage);
let visit_cnt = await storage.get("VisitCount") as number;
if (visit_cnt == null) visit_cnt = 0;
console.log(`[OnJoin] le nombre de visites de ${client.sessionId} : ${visit_cnt}`)
// [DataStorage] Mettre à jour le nombre de visites du joueur et ensuite enregistrer le stockage
await storage.set("VisitCount", ++visit_cnt);
// Gérer l'objet Player en utilisant sessionId, une valeur clé unique de l'objet client.
// Le client peut vérifier les informations sur l'objet joueur ajouté par set en ajoutant l'événement add_OnAdd à l'objet players.
this.state.players.set(client.sessionId, player);
// Vérifier le nombre de joueurs dans la salle après qu'un joueur ait rejoint.
this.CheckPlayerNumber();
}
onTick(deltaTime: number): void {
// Il est appelé de manière répétée à chaque heure définie sur le serveur, et un événement d'intervalle spécifique peut être géré en utilisant deltaTime.
}
async onLeave(client: SandboxPlayer, consented?: boolean) {
// En définissant allowReconnection, il est possible de maintenir la connexion pour le circuit, mais de nettoyer immédiatement dans le guide de base.
// Le client peut vérifier les informations sur l'objet joueur supprimé en ajoutant l'événement add_OnRemove à l'objet players.
this.state.players.delete(client.sessionId);
}
}