Bot 플레이어 생성 가이드
봇 플레이어는 멀티플레이어 월드를 시작할 충분한 사람이 없거나, 플레이어가 월드 중에 나갈 때 채우기 위해 사용됩니다.
봇 플레이어의 행동 방식은 각 콘텐츠에 맞게 구현되어야 합니다.
이 가이드는 봇 플레이어를 만드는 일반적인 방법을 설명합니다.
📘 봇 플레이어 생성 가이드는 멀티플레이어 가이드를 기반으로 합니다. [멀티플레이 제작하기]
1단계: 봇 플레이어 만들기
1-1. 멀티플레이어 스키마에 IsBot이라는 불리언 값을 추가합니다.

1-2. 아래의 함수를 정의하여 서버 스크립트 index.ts에서 봇 플레이어를 생성하고 원하는 지점에서 호출합니다.
// `CreateBot()` 메서드는 주어진 `userId`로 봇 플레이어를 생성하는 데 사용됩니다.
CreateBot(userId: string) {
// 제공된 `userId`를 사용하여 봇 플레이어의 세션 ID를 생성합니다.
const sessionId = "Bot_" + userId;
// 동일한 세션 ID를 가진 봇 플레이어가 이미 존재하는지 확인합니다. 그렇다면 중복 생성 없이 반환합니다.
if (this.state.players.has(sessionId)) {
return;
}
// 봇 플레이어를 위한 새로운 `Player` 객체를 생성합니다.
const player: Player = new Player();
player.sessionId = sessionId;
if (userId) {
player.zepetoUserId = userId;
}
player.isBot = true;
// 세션 ID를 키로 사용하여 상태의 플레이어 맵에 봇 플레이어를 추가합니다.
this.state.players.set(player.sessionId, player);
this._botMap.set(sessionId, player);
}
👍 팁
- 특정 사용자의 userId는 봇 플레이어 캐릭터가 생성되기 위해 미리 저장됩니다.
- 서버의 OnJoin에 연결된 클라이언트의 userId를 확인하여 특정 사용자의 UserId를 확인할 수 있습니다. 아래 스크립트를 서버 스크립트에 작성한 후 관련 월드에서 연결하세요.
onJoin(client: SandboxPlayer) {
console.log(client.userId);
}
단계 2: 클라이언트에서 봇 플레이어 만들기
2-1. 서버에서 특정 시점에 봇 플레이어를 생성하면 클라이언트는 이를 OnJoinPlayer()에서 새로운 플레이어로 인식합니다.
- 프로젝트 만들기 > 생성 > ZEPETO > TypeScript로 이름을 BotPlayerManager로 변경합니다.
- OnAddedPlayer()에서 각 플레이어를 생성하는 로직을 추가하고, 봇 플레이어를 구분하고 그들의 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;
// 현재 방과 봇 플레이어 데이터를 저장할 개인 변수들입니다.
private _room: Room;
private _botMapData: Map<string, ZepetoCharacter> = new Map<string, ZepetoCharacter>();
Start() {
// `ZepetoWorldMultiplay` 컴포넌트에서 `RoomJoined` 이벤트를 수신합니다.
this.zepetoWorldMultiplay.RoomJoined += (room: Room) => {
this._room = room;
}
// 새로 추가된 플레이어를 처리하기 위해 `ZepetoPlayers.instance`에서 `OnAddedPlayer` 이벤트를 수신합니다.
ZepetoPlayers.instance.OnAddedPlayer.AddListener((userId: string) => {
// `userId`를 사용하여 방 상태에서 현재 플레이어 데이터를 가져옵니다.
const currentPlayer = this._room.State.players.get_Item(userId);
// 플레이어가 봇인지 확인하고, 그렇다면 그들을 봇 플레이어로 설정합니다.
if (currentPlayer.isBot) {
this.SetBotPlayer(currentPlayer.sessionId);
}
});
}
}
2-2. SetBotPlayer 함수를 작성하여 봇 플레이어에 태그와 동기화 구성 요소를 추가하고 이를 제어하는 스크립트를 생성합니다.
- 봇 플레이어 데이터를 관리하기 위해 Map 형식으로 _botMapData를 설정하여 저장합니다.
// `SetBotPlayer()` 메서드는 플레이어를 봇으로 설정하는 데 사용됩니다.
SetBotPlayer(userId: string) {
// `userId`를 사용하여 봇 플레이어와 관련된 ZEPETO 캐릭터를 가져옵니다.
const bot = ZepetoPlayers.instance.GetPlayer(userId).character;
// 식별을 위해 캐릭터의 이름을 `userId`로 설정합니다.
bot.gameObject.name = userId;
// `userId`를 키로 사용하여 `_botMapData` 맵에 봇 플레이어의 데이터를 저장합니다.
this._botMapData.set(userId, bot);
}
👍 팁 SetBotPlayer()에 추가 스크립트나 설정을 추가하여 봇 플레이어의 행동을 제어할 수 있습니다.
3단계: 클라이언트에 봇 플레이어 버튼 생성
시작하기 위해 특정 수의 플레이어가 필요한 월드의 경우, 때때로 플레이어가 충분하지 않아 월드가 시작되기까지 오랜 시간을 기다려야 합니다.
이 경우, Bot 플레이어를 추가하여 월드를 시작할 수 있습니다.
3-1. index.ts에서 서버가 클라이언트로부터 메시지를 받을 때 CreateBot()을 실행하도록 함수를 등록합니다.
async OnCreate() {
// 주어진 userId로 봇 플레이어를 생성하는 "CreateBot" 메시지를 처리합니다.
this.onMessage("CreateBot", (client, message) => {
this.CreateBot(message);
});
}
3-2. 클라이언트 스크립트 BotPlayerManager.ts에서 서버에 "CreateBot" 메시지를 보내는 함수를 작성합니다.
- 함수를 실행하는 방법은 버튼을 눌러 메시지를 보내는 것입니다.
- 생성할 Bot 플레이어의 사용자 ID를 문자열로 메시지를 통해 보냅니다.
public buttonCreateBot: Button;
public botPlayerId: string;
Start() {
// "Create Bot" 버튼에 클릭 리스너를 추가하여 봇 플레이어를 생성하는 메시지를 보냅니다.
this.buttonCreateBot.onClick.AddListener(() => {
this._room.Send("CreateBot", this.botPlayerId);
});
}
3-3. 이제 서버와 런타임을 실행하면 버튼을 누를 때 봇 플레이어가 생성되는 것을 볼 수 있습니다.

4단계: 봇 플레이어 추가로 월드 시작하기
월드 시작에 필요한 플레이어가 부족할 때, 봇 플레이어를 추가하여 월드를 시작할 수 있습니다.
4-1. 서버 스크립트에서 OnJoin 중에 다음 코드를 추가하여 플레이어 수를 확인하고 최소 네 명의 플레이어가 있을 때 월드를 시작합니다.
- CreateBot()에서 플레이어 수를 확인하는 함수를 추가합니다.
- StartWorld() 함수에서 플레이 수를 카운트하는 변수를 추가합니다.
async onJoin(client: SandboxPlayer) {
// 플레이어가 입장한 후 방의 플레이어 수를 확인합니다.
this.CheckPlayerNumber();
}
// `CheckPlayerNumber()` 메서드는 방의 플레이어 수를 확인하고 최소 네 명의 플레이어가 있을 경우 월드를 시작합니다.
CheckPlayerNumber() {
// 방의 현재 플레이어 수를 콘솔에 출력합니다.
console.log(`플레이어 수, ${this.state.players.size}`);
// 방에 최소 네 명의 플레이어가 있을 경우 월드를 시작합니다.
if (this.state.players.size >= 4) {
this.StartWorld();
}
}
// `CreateBot()` 메서드는 주어진 `userId`로 봇 플레이어를 생성하는 데 사용됩니다.
CreateBot(userId: string) {
// 제공된 `userId`를 사용하여 봇 플레이어의 세션 ID를 생성합니다.
const sessionId = "Bot_" + userId;
// 동일한 세션 ID를 가진 봇 플레이어가 이미 존재하는지 확인합니다. 존재할 경우 중복 생성 없이 반환합니다.
if (this.state.players.has(sessionId)) {
return;
}
// 봇 플레이어를 위한 새로운 `Player` 객체를 생성합니다.
const player: Player = new Player();
player.sessionId = sessionId;
if (userId) {
player.zepetoUserId = userId;
}
player.isBot = true;
// 세션 ID를 키로 사용하여 상태의 플레이어 맵에 봇 플레이어를 추가합니다.
this.state.players.set(player.sessionId, player);
this._botMap.set(sessionId, player);
// 봇 플레이어를 추가한 후 방의 플레이어 수를 확인합니다.
this.CheckPlayerNumber();
}
private playTime: number = 0;
// `StartWorld()` 메서드는 플레이 시간을 증가시키고 모든 클라이언트에 "StartWorld" 메시지를 방송합니다.
StartWorld() {
this.playTime += 1;
// 월드의 시작과 현재 플레이 시간을 나타내는 메시지를 출력합니다.
console.log("StartWorld!");
this.broadcast("StartWorld", this.playTime);
}
- 서버에서 실제 플레이어가 방에 들어오면 OnJoin이 실행됩니다. 따라서 CreateBot을 통해 봇 플레이어가 생성되고 플레이어가 OnJoin을 통해 들어올 때 checkPlayerNumber()는 인원 수를 추가합니다.
4-2. 클라이언트 스크립트인 BotPlayerManager.ts에서 서버로부터 StartWorld 메시지를 수신할 때 실행되는 StartWorld()를 작성합니다.
Start() {
// `ZepetoWorldMultiplay` 컴포넌트에서 `RoomJoined` 이벤트를 수신합니다.
this.zepetoWorldMultiplay.RoomJoined += (room: Room) => {
// "StartWorld" 메시지 유형에 대한 메시지 핸들러를 추가합니다.
this._room.AddMessageHandler("StartWorld", (playTime: number) => {
this.StartWorld(playTime);
});
}
// 제공된 `playTime`으로 월드가 시작될 때 `StartWorld()` 메서드가 호출됩니다.
StartWorld(playTime: number) {
// `playTime`과 함께 월드 시작 메시지를 출력합니다.
console.log(`Start World : ${playTime}`);
}
4-3. 실행 중에 봇 플레이어를 포함하여 4명 이상의 플레이어가 있을 경우, 서버 콘솔과 클라이언트 콘솔에 'World Start'라는 로그가 표시됩니다.

5단계: 봇 플레이어 위치 동기화
아래는 추가된 봇 플레이어를 로컬 플레이어 위치로 이동시키고 이동 위치를 동기화하는 샘플 코드입니다.
5-1. 먼저, 서버의 index.ts에서 클라이언트로부터 메시지 MoveBot을 수신할 때 봇 플레이어를 이동시키는 코드를 작성합니다.
async OnCreate() {
// "MoveBot" 메시지를 처리하여 봇 플레이어를 지정된 위치로 이동시킵니다.
this.onMessage("MoveBot", (client, message) => {
this.MoveBot(client, message);
});
}
// `MoveBot()` 메서드는 수신된 메시지를 기반으로 봇 플레이어를 지정된 위치로 이동시킵니다.
MoveBot(client: SandboxPlayer, message: string) {
// 클라이언트로부터 수신된 JSON 메시지를 파싱하여 위치 정보를 추출합니다.
const position = JSON.parse(message);
// 사용자의 세션 ID와 파싱된 위치 데이터를 포함하는 새로운 메시지 객체를 생성합니다.
const newMessage = {
user: client.sessionId,
positionX: position.x,
positionY: position.y,
positionZ: position.z
}
// 새로운 메시지 데이터를 JSON 문자열로 모든 클라이언트에 "MoveBotToPosition" 메시지를 브로드캐스트합니다.
this.broadcast("MoveBotToPosition", JSON.stringify(newMessage));
}
5-2. 클라이언트 스크립트인 BotPlayerManager.ts에서 buttonCallBot이 눌릴 때 로컬 플레이어 위치를 서버로 전송하는 SendBotPosition()을 작성합니다.
- 그런 다음 서버에서 MoveBotToPosition 메시지를 수신할 때 모든 봇 플레이어를 메시지에 포함된 위치 정보로 이동시키는 코드를 작성하십시오.
public buttonCallBot: Button;
Start(){
// `ZepetoWorldMultiplay` 컴포넌트에서 `RoomJoined` 이벤트를 수신합니다.
this.zepetoWorldMultiplay.RoomJoined += (room: Room) => {
this._room = room;
// "StartWorld" 메시지 유형에 대한 메시지 핸들러를 추가합니다.
this._room.AddMessageHandler("StartWorld", (playTime: number) => {
this.StartWorld(playTime);
});
// "Call Bot" 버튼에 클릭 리스너를 추가하여 봇 플레이어 위치를 전송하는 메시지를 보냅니다.
this.buttonCallBot.onClick.AddListener(() => {
this.SendBotPosition();
});
}
// 이 메서드는 로컬 플레이어의 캐릭터 위치를 서버에 전송하여 봇 이동 동기화를 수행합니다.
SendBotPosition() {
// 로컬 플레이어의 캐릭터 위치를 가져옵니다.
const localPlayerPosition = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character.transform.position;
// 로컬 플레이어의 캐릭터의 x, y, z 좌표를 포함하는 위치 객체를 생성합니다.
const position = {
x: localPlayerPosition.x,
y: localPlayerPosition.y,
z: localPlayerPosition.z
}
// 위치 객체를 JSON 문자열로 변환하고 "MoveBot" 메시지 유형으로 서버에 전송합니다.
this._room.Send("MoveBot", JSON.stringify(position));
}
MoveBotToPosition(message) {
// 클라이언트에서 수신한 JSON 메시지를 구문 분석하여 위치 정보를 추출합니다.
const jsonMessage = JSON.parse(message);
const position = new Vector3(jsonMessage.positionX, jsonMessage.positionY, jsonMessage.positionZ);
// `_botMapData` 맵의 각 봇 캐릭터를 지정된 위치로 이동시키고 x 및 z 축에 작은 무작위 오프셋을 추가합니다.
this._botMapData.forEach((character: ZepetoCharacter) => {
// `MoveToPosition()` 메서드를 사용하여 캐릭터를 지정된 위치로 이동시킵니다.
// 여기서, 봇의 자연스러운 움직임을 위해 목표 위치에 작은 무작위 오프셋을 추가합니다.
character.MoveToPosition(position + new Vector3(Random.Range(0.5, 1), 0, Random.Range(0.5, 1)));
});
}
5-3. 이제 런타임에 봇 플레이어를 생성하고 buttonCallBot 버튼을 누르면 생성된 봇 플레이어가 로컬 플레이어 캐릭터 위치로 이동하는 것을 볼 수 있습니다.

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 {
// Public properties to reference necessary components and settings from the Inspector.
public zepetoWorldMultiplay: ZepetoWorldMultiplay;
public buttonCreateBot: Button;
public buttonCallBot: Button;
public botPlayerId: string;
// Private variables to store the current room and bot player data.
private _room: Room;
private _botMapData: Map<string, ZepetoCharacter> = new Map<string, ZepetoCharacter>();
Start() {
// Listen for the `RoomJoined` event from the `ZepetoWorldMultiplay` component.
this.zepetoWorldMultiplay.RoomJoined += (room: Room) => {
this._room = room;
// Add a message handler for the "StartWorld" message type.
this._room.AddMessageHandler("StartWorld", (playTime: number) => {
this.StartWorld(playTime);
});
}
// Listen for the `OnAddedPlayer` event from `ZepetoPlayers.instance` to handle newly added players.
ZepetoPlayers.instance.OnAddedPlayer.AddListener((userId: string) => {
// Get the current player data from the room state using the `userId`.
const currentPlayer = this._room.State.players.get_Item(userId);
// Check if the player is a bot, and if so, set them as a bot player.
if (currentPlayer.isBot) {
this.SetBotPlayer(currentPlayer.sessionId);
}
});
// Add a click listener to the "Create Bot" button to send a message to create a bot player.
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);
});
}
// Add a click listener to the "Call Bot" button to send a message to send a bot player position.
this.buttonCallBot.onClick.AddListener(() => {
this.SendBotPosition();
});
}
// The `SetBotPlayer()` method is used to set a player as a bot.
SetBotPlayer(userId: string) {
// Get the ZEPETO character associated with the bot player using their `userId`.
const bot = ZepetoPlayers.instance.GetPlayer(userId).character;
// Set the name of the character to the `userId` for identification.
bot.gameObject.name = userId;
// Store the bot player's data in the `_botMapData` map using their `userId` as the key.
this._botMapData.set(userId, bot);
}
// The `StartWorld()` method is called when the world starts with the provided `playTime`.
StartWorld(playTime: number) {
// Print the world start message along with the `playTime`.
console.log(`Start World : ${playTime}`);
}
// This method sends the position of the local player's character to the server for bot movement synchronization.
SendBotPosition() {
// Get the position of the local player's character.
const localPlayerPosition = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character.transform.position;
// Create a position object containing the x, y, and z coordinates of the local player's character.
const position = {
x: localPlayerPosition.x,
y: localPlayerPosition.y,
z: localPlayerPosition.z
}
// Convert the position object to a JSON string and send it to the server with the "MoveBot" message type.
this._room.Send("MoveBot", JSON.stringify(position));
}
// This method is called when the server receives the "MoveBot" message from a client and moves the bot characters to the specified position.
MoveBotToPosition(message) {
// Parse the JSON message received from the client to extract the position information.
const jsonMessage = JSON.parse(message);
const position = new Vector3(jsonMessage.positionX, jsonMessage.positionY, jsonMessage.positionZ);
// Move each bot character in the `_botMapData` map to the specified position with a small random offset on the x and z axes.
this._botMapData.forEach((character: ZepetoCharacter) => {
// The `MoveToPosition()` method is used to move the character to the specified position.
// Here, a small random offset is added to the target position to create a natural-looking movement for the bots.
character.MoveToPosition(position + new Vector3(Random.Range(0.5, 1), 0, Random.Range(0.5, 1)));
});
}
}
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>();
// 봇 플레이어의 맵 데이터를 _botMap으로 저장합니다.
private _botMap: Map<string, Player> = new Map<string, Player>();
private playTime: number = 0;
constructor() {
super();
}
onCreate(options: SandboxOptions) {
// Room 객체가 생성될 때 호출됩니다.
// 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;
}
});
// 주어진 userId로 봇 플레이어를 생성하는 "CreateBot" 메시지를 처리합니다.
this.onMessage("CreateBot", (client, message) => {
this.CreateBot(message);
});
// 지정된 위치로 봇 플레이어를 이동시키는 "MoveBot" 메시지를 처리합니다.
this.onMessage("MoveBot", (client, message) => {
this.MoveBot(client, message);
});
}
// `CreateBot()` 메서드는 주어진 `userId`로 봇 플레이어를 생성하는 데 사용됩니다.
CreateBot(userId: string) {
// 제공된 `userId`를 사용하여 봇 플레이어의 세션 ID를 생성합니다.
const sessionId = "Bot_" + userId;
// 동일한 세션 ID를 가진 봇 플레이어가 이미 존재하는지 확인합니다. 존재하면 중복 생성을 방지합니다.
if (this.state.players.has(sessionId)) {
return;
}
// 봇 플레이어를 위한 새로운 `Player` 객체를 생성합니다.
const player: Player = new Player();
player.sessionId = sessionId;
if (userId) {
player.zepetoUserId = userId;
}
player.isBot = true;
// 세션 ID를 키로 사용하여 상태의 플레이어 맵에 봇 플레이어를 추가합니다.
this.state.players.set(player.sessionId, player);
this._botMap.set(sessionId, player);
// 봇 플레이어를 추가한 후 방의 플레이어 수를 확인합니다.
this.CheckPlayerNumber();
}
// `CheckPlayerNumber()` 메서드는 방의 플레이어 수를 확인하고, 최소 4명의 플레이어가 있을 경우 월드를 시작합니다.
CheckPlayerNumber() {
// 방의 현재 플레이어 수를 콘솔에 출력합니다.
console.log(`player Number, ${this.state.players.size}`);
// 방에 최소 4명의 플레이어가 있으면 월드를 시작합니다.
if (this.state.players.size >= 4) {
this.StartWorld();
}
}
// `StartWorld()` 메서드는 플레이 시간을 증가시키고 "StartWorld" 메시지를 모든 클라이언트에 방송합니다.
StartWorld() {
this.playTime += 1;
// 월드의 시작과 현재 플레이 시간을 나타내는 메시지를 출력합니다.
console.log("Start World!");
this.broadcast("StartWorld", this.playTime);
}
// `MoveBot()` 메서드는 수신된 메시지를 기반으로 봇 플레이어를 지정된 위치로 이동시킵니다.
MoveBot(client: SandboxPlayer, message: string) {
// 클라이언트로부터 수신된 JSON 메시지를 파싱하여 위치 정보를 추출합니다.
const position = JSON.parse(message);
// 사용자의 세션 ID와 파싱된 위치 데이터를 포함하는 새로운 메시지 객체를 생성합니다.
const newMessage = {
user: client.sessionId,
positionX: position.x,
positionY: position.y,
positionZ: position.z
}
// 새로운 메시지 데이터를 JSON 문자열로 모든 클라이언트에 "MoveBotToPosition" 메시지를 방송합니다.
this.broadcast("MoveBotToPosition", JSON.stringify(newMessage));
}
async onJoin(client: SandboxPlayer) {
// schemas.json에 정의된 플레이어 객체를 생성하고 초기 값을 설정합니다.
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] 들어온 플레이어의 DataStorage 로드
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] ${client.sessionId}의 방문 수 : ${visit_cnt}`)
// [DataStorage] 플레이어의 방문 수를 업데이트하고 저장합니다.
await storage.set("VisitCount", ++visit_cnt);
// 세션Id를 사용하여 플레이어 객체를 관리합니다. 이는 클라이언트 객체의 고유 키 값입니다.
// 클라이언트는 플레이어 객체에 추가된 정보를 확인할 수 있습니다.
this.state.players.set(client.sessionId, player);
// 플레이어가 입장한 후 방의 플레이어 수를 확인합니다.
this.CheckPlayerNumber();
}
onTick(deltaTime: number): void {
// 서버에서 설정된 시간마다 반복적으로 호출되며, 특정 간격 이벤트를 deltaTime을 사용하여 관리할 수 있습니다.
}
async onLeave(client: SandboxPlayer, consented?: boolean) {
// allowReconnection을 설정하면 회로를 위해 연결을 유지할 수 있지만, 기본 가이드에서는 즉시 정리합니다.
// 클라이언트는 삭제된 플레이어 객체에 대한 정보를 확인할 수 있습니다.
this.state.players.delete(client.sessionId);
}
}