Isyarat
API ZepetoWorldContent memungkinkan Anda untuk mengatur thumbnail untuk kategori gestur/pose yang diinginkan dan mengaktifkan gestur/pose tertentu ketika thumbnail diklik.

Untuk menggunakan API ZepetoWorldContent, Anda harus menulis pernyataan impor sebagai berikut.
import { OfficialContentType, WorldService, ZepetoWorldContent, Content } from 'ZEPETO.World';
Informasi variabel anggota dan fungsi dari kelas Konten yang berisi informasi gerakan/pose adalah sebagai berikut:
API | Deskripsi |
|---|---|
publik get Id(): string | Id Unik Konten |
publik get Title(): string | Teks judul gerakan, pose - Bahasa akan secara otomatis diterjemahkan tergantung pada bahasa perangkat |
publik get Thumbnail(): UnityEngine.Texture2D | thumbnail 2D |
publik get AnimationClip(): UnityEngine.AnimationClip | Clip Animasi Gerakan |
publik get IsDownloadedThumbnail(): boolean | Fungsi untuk menentukan apakah Anda telah mengunduh thumbnail ini sebelumnya |
publik get IsDownloadedAnimation(): boolean | Fungsi untuk menentukan apakah Anda telah mengunduh clip animasi ini sebelumnya |
publik DownloadAnimation($complete: System.Action):void | Fungsi unduh clip animasi yang menerima callback selesai dengan faktor - Jika IsDownloadedAnimation() adalah false, implementasikan DownloadAnimation() untuk dipanggil. |
publik DownloadThumbnail($complete: System.Action):void | Fungsi untuk mengunduh thumbnail - Jika IsDownloadedThumbnail() adalah false, implementasikan DownloadThumbnail() untuk dipanggil. |
OfficialContentType : enum | Tipe konten (Dunia 1.9.0 dan lebih tinggi) - Gerakan = 2 - Pose = 4 - Selfie = 8 - GestureGreeting = 16 - GesturePose = 32 - GestureAffirmation = 64 - GestureDancing = 128 - GestureDenial = 256 - GestureEtc = 512 - Semua = 14 |
- Anda dapat menggunakan fungsi yang ada, public DownloadThumbnail($character: ZEPETO_Character_Controller.ZepetoCharacter, $complete: System.Action):void, tanpa masalah terkait fungsionalitas. Namun, karena tidak lagi menerima karakter Zepeto sebagai argumen, silakan gunakan fungsi yang baru dimodifikasi public DownloadThumbnail($complete: System.Action):void sebagai gantinya.
LANGKAH 1 : Siapkan UI
LANGKAH 1-1 : Buat tombol gestur
1) Tambahkan Hierarchy > UI > Canvas dan atur Urutan Sortir ke 2 untuk menghindari tertutup oleh UI lainnya.

2) Tambahkan Hierarki > UI > Tombol.

LANGKAH 1-2 : Atur panel gestur
1) Tambahkan Hierarki > Buat Objek Kosong dan ganti namanya menjadi PanelParent.

2) Tambahkan Hierarki > UI > Panel sebagai anak dari PanelParent.

3) Tombol tutup: Setelah menambahkan UI > Tombol, tambahkan event onClick untuk menonaktifkan panel gestur.

4) Tombol buka: Silakan tambahkan event onClick yang mengaktifkan panel gestur ke tombol buka yang dibuat di atas.

5) Tambahkan gambar untuk berfungsi sebagai area judul.

6) Konfigurasikan tampilan gulir untuk menampilkan thumbnail gestur.
- Tambahkan Hierarki > UI > Tampilan Gulir.
- Centang Horizontal dan nonaktifkan gambar bilah gulir karena Anda hanya akan menggunakan gulir vertikal dan gulir horizontal tidak akan diperlukan.
- Tambahkan tata letak Grid ke Konten di Tampilan Gulir untuk menyelaraskan thumbnail dalam pola grid.
- Tambahkan Pengatur Ukuran Konten untuk membuat ukuran objek sesuai dengan ukuran konten.
- Ketika Anda menerapkan skrip, Anda harus mengatur konten di Tampilan Gulir sebagai induk dari thumbnail gestur (agar seluruh area dikenali dan digulir)

7) Konfigurasikan tab berdasarkan jenis gestur.
- Tambahkan Hierarki > Buat Objek Kosong sebagai anak dari Panel dan ganti namanya menjadi GestureTitle.
- Ini adalah objek induk dari tombol toggle.
- Tambahkan Tata Letak Horizontal untuk menyelaraskan tab secara horizontal.
- Tambahkan komponen Grup Toggle.
👍 Untuk mengonfigurasi lebih banyak tab, tambahkan Hierarki > UI > Tampilan Gulir dan centang Horizontal di opsi Tampilan Gulir.

8) Tambahkan teks yang akan digunakan sebagai tombol toggle sebagai anak dari GestureTitle, dan ganti dengan Semua.
- Mengatur warna teks menjadi abu-abu.
- Tambahkan teks yang disorot yang akan ditampilkan saat dicentang sebagai anak dari teks.
- Atur konten font, ukuran, dan ketebalan sama, dan atur warna menjadi hitam.
- Tambahkan komponen Toggle.
- Tentukan objek induk dalam grup.
- Tambahkan teks yang disorot yang Anda tambahkan sebagai anak ke Grafik
- Periksa isOn hanya untuk semua komponen toggle yang akan ditampilkan terlebih dahulu.
- Buat kedua tombol toggle Gesture dan Pose dengan cara yang sama.

LANGKAH 1-3 : Buat prefab thumbnail
Gunakan metode membuat tombol thumbnail sebagai prefab dan kemudian menghasilkan sebagai instance dalam skrip.
1) Tambahkan UI > Tombol sebagai anak dari Konten di Scroll View dan ganti namanya menjadi preThumb.
2) Silakan ganti namanya menjadi Thumb setelah menambahkan Gambar Mentah.
- Gambar ini akan menjadi thumbnail. Sesuaikan ukuran dengan tepat.
3) Tambahkan Teks.
- Atur posisi untuk memusatkan bagian bawah gambar.
- Sesuaikan ukuran dan ketebalan tulisan, dan tambahkan Content Size Fitter.
- Horizontal Fit : Ukuran yang Diutamakan
- Vertical Fit : Ukuran yang Diutamakan
4) Jika pengaturan sudah selesai, silakan jadikan sebagai Prefab dan letakkan di folder Resources.


LANGKAH 1-4 : Video Panduan Pengaturan UI
👍 Nilai ukuran dan posisi UI yang ditunjukkan dalam video disarankan, tetapi Anda dapat memodifikasinya sesuai dengan nilai yang Anda inginkan!
Setelah pengaturan UI selesai, lanjutkan ke Scripting.
LANGKAH 2 : Tulis skrip
Skrip ini berdasarkan permainan tunggal.
LANGKAH 2-1 : Thumbnail
- Proyek > Buat > ZEPETO > TypeScript dan ganti namanya menjadi Thumbnail.
- Tulis skrip contoh seperti di bawah ini.
- Ini adalah skrip yang mengatur informasi konten gerakan (judul, gambar) ke dalam UI.
import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
import { Content } from 'ZEPETO.World';
import { RawImage, Text } from 'UnityEngine.UI';
import { Texture2D } from 'UnityEngine';
export default class Thumbnail extends ZepetoScriptBehaviour {
@HideInInspector() public content: Content;
Start() {
this.GetComponentInChildren<Text>().text = this.content.Title;
this.GetComponentInChildren<RawImage>().texture = this.content.Thumbnail as Texture2D;
}
}- Setelah membuat skrip, buka prefab preThumb dan tambahkan skrip tersebut.

LANGKAH 2-2 : GestureLoader
- Buat Hierarki > Buat Objek Kosong dan ganti namanya menjadi GestureLoader.
- Buat Proyek > Buat > ZEPETO > TypeScript dan ganti namanya menjadi GestureLoader.
- Tulis skrip contoh seperti di bawah ini.
import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
import { LocalPlayer, SpawnInfo, ZepetoCharacter, ZepetoPlayers } from 'ZEPETO.Character.Controller';
import { OfficialContentType, WorldService, ZepetoWorldContent, Content } from 'ZEPETO.World';
import { RawImage, Text, Button } from 'UnityEngine.UI';
import { GameObject, Texture2D, Transform, WaitUntil } from 'UnityEngine';
import Thumbnail from './Thumbnail';
export default class GestureLoader extends ZepetoScriptBehaviour {
@HideInInspector() public contents: Content[] = [];
@HideInInspector() public thumbnails: GameObject[] = [];
@SerializeField() private _count: number = 50;
@SerializeField() private _contentsParent: Transform;
@SerializeField() private _prefThumb: GameObject;
private _myCharacter: ZepetoCharacter;
Start() {
// Membuat Karakter
ZepetoPlayers.instance.CreatePlayerWithUserId(WorldService.userId, new SpawnInfo(), true);
ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
this._myCharacter = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character;
// Untuk mengambil thumbnail dengan karakter saya, Anda perlu meminta konten setelah karakter dibuat.
this.ContentRequest();
});
}
// 1. Menerima konten dari server
private ContentRequest() {
// Semua Tipe Permintaan
ZepetoWorldContent.RequestOfficialContentList(OfficialContentType.All, contents => {
this.contents = contents;
for (let i = 0; i < this._count; i++) {
if (!this.contents[i].IsDownloadedThumbnail) {
// Ambil foto thumbnail menggunakan karakter saya
this.contents[i].DownloadThumbnail(() =>{
this.CreateThumbnailObjcet(this.contents[i]);
});
} else {
this.CreateThumbnailObjcet(this.contents[i]);
}
}
});
}
// 2. Membuat Objek Thumbnail
private CreateThumbnailObjcet(content: Content) {
const newThumb: GameObject = GameObject.Instantiate(this._prefThumb, this._contentsParent) as GameObject;
newThumb.GetComponent<Thumbnail>().content = content;
// Listener Tombol untuk setiap thumbnail
newThumb.GetComponent<Button>().onClick.AddListener(() => {
this.LoadAnimation(content);
});
this.thumbnails.push(newThumb);
}
// 3. Memuat Animasi
private LoadAnimation(content: Content) {
// Verifikasi pemuatan animasi
if (!content.IsDownloadedAnimation) {
// Jika animasi belum diunduh, unduh itu.
content.DownloadAnimation(() => {
// putar klip animasi
this._myCharacter.SetGesture(content.AnimationClip);
});
} else {
this._myCharacter.SetGesture(content.AnimationClip);
}
}
}- Count adalah jumlah maksimum gerakan yang akan diunduh di setiap tab. Jika Anda mengatur ke angka yang lebih besar dari 100, mungkin ada kesalahan selama proses pengunduhan thumbnail, jadi harap atur hanya sebanyak yang Anda butuhkan.
Skrip mengalir sebagai berikut:
1) Panggil fungsi kustom ContentsRequest() untuk menghasilkan thumbnail setelah memuat karakter ZEPETO.
- Fungsi ContentsRequest() menerima informasi konten dengan memisahkan gerakan dan pose, masing-masing.
- Jika ada thumbnail yang sudah ada, itu akan dilewati; jika tidak, thumbnail akan diambil.
- Data thumbnail yang diambil disimpan dalam daftar masing-masing.

LANGKAH 2-3 : UIController
- Buat Hierarki > Buat Objek Kosong dan ganti namanya menjadi UIContoller.
- Buat Proyek > Buat > ZEPETO > TypeScript dan ganti namanya menjadi UIContoller.
- Tulis skrip contoh seperti di bawah ini.
import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
import { Button, RawImage, Text, Toggle } from 'UnityEngine.UI';
import { LocalPlayer, ZepetoCharacter, ZepetoPlayers, ZepetoScreenTouchpad } from 'ZEPETO.Character.Controller';
import { OfficialContentType, Content } from 'ZEPETO.World';
import { Object, GameObject, Transform } from 'UnityEngine';
import GestureLoader from './GestureLoader';
import Thumbnail from './Thumbnail';
export default class UIController extends ZepetoScriptBehaviour {
@SerializeField() private _closeButton : Button;
@SerializeField() private _typeToggleGroup : Toggle[];
private _gestureLodaer: GestureLoader;
private _myCharacter: ZepetoCharacter;
Start() {
this._gestureLodaer = Object.FindObjectOfType<GestureLoader>();
ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
this._myCharacter = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character;
// Jika mengklik touchpad, batalkan gerakan
Object.FindObjectOfType<ZepetoScreenTouchpad>().OnPointerDownEvent.AddListener(() => {
this.StopGesture();
});
// Jika mengklik tombol tutup, batalkan gerakan
this._closeButton.onClick.AddListener(() => {
this.StopGesture();
});
});
// Pendengar UI
this._typeToggleGroup[0].onValueChanged.AddListener(() => {
this.SetCategoryUI(OfficialContentType.All);
});
this._typeToggleGroup[1].onValueChanged.AddListener(() => {
this.SetCategoryUI(OfficialContentType.Gesture);
});
this._typeToggleGroup[2].onValueChanged.AddListener(() => {
this.SetCategoryUI(OfficialContentType.Pose);
});
}
// Set UI Kategori Toggle
private SetCategoryUI(category: OfficialContentType) {
if (category == OfficialContentType.All) {
this._gestureLodaer.thumbnails.forEach((Obj) => {
Obj.SetActive(true);
});
} else {
for (let i = 0; i < this._gestureLodaer.thumbnails.length; i++) {
const content = this._gestureLodaer.thumbnails[i].GetComponent<Thumbnail>().content;
if (content.Keywords.includes(category)) {
this._gestureLodaer.thumbnails[i].SetActive(true);
} else {
this._gestureLodaer.thumbnails[i].SetActive(false);
}
}
}
}
private StopGesture() {
this._myCharacter.CancelGesture();
}
}Alur skrip adalah sebagai berikut:
- Sentuh touchpad atau tombol tutup untuk membatalkan pemutaran menggunakan fungsi CancelGesture().
- Ketuk tab (tombol toggle) untuk memanggil fungsi kustom SetCategoryUI().
- Fungsi SetCategoryUI() menggunakan informasi konten gestur di setiap thumbnail untuk mengaturnya untuk setiap kategori yang sesuai.
- Aktifkan jika ini adalah jenis yang berlaku, dan nonaktifkan jika tidak.
Setelah menyelesaikan scripting, tetapkan Tombol Tutup, TypeToggleGroup ke Inspector.
- Masuk ke Type Toggle Group adalah Toggle yang merupakan anak dari Toggle Group di panel gestur.

LANGKAH 3 : Jalankan
❗️ Peringatan Sebelum bermain, nonaktifkan PanelParent agar hanya tombol buka yang terlihat saat bermain.

LANGKAH 4 : Sinkronkan gerakan multi-pemain
- Dalam kasus multi-pemain, kode sinkronisasi harus ditambahkan yang menerima nilai informasi gerakan yang diambil oleh pemain tertentu dan menerapkannya ke semua pemain yang mengakses Ruangan.
- Kuncinya adalah mengirim dan menerima Pesan Ruangan antara server dan klien tentang pemain mana yang melakukan gerakan mana.
LANGKAH 4-1 : Kode Klien
Thumbnail - Multiplay
- Tulis skrip yang sama seperti yang diterapkan dalam kode klien single-play.
import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
import { Content } from 'ZEPETO.World';
import { RawImage, Text } from 'UnityEngine.UI';
import { Texture2D } from 'UnityEngine';
export default class Thumbnail extends ZepetoScriptBehaviour {
@HideInInspector() public content: Content;
Start() {
this.GetComponentInChildren<Text>().text = this.content.Title;
this.GetComponentInChildren<RawImage>().texture = this.content.Thumbnail as Texture2D;
}
}
GestureLoader - Multiplay
- Secara default, skrip yang diterapkan dalam kode klien single-play ditulis dengan cara yang sama.
- Selain itu, klien mendeklarasikan antarmuka untuk berisi PlayerGestureInfo.
- Saat mengirim informasi Anda ke server: lihat SendMyGesture() Fungsi Kustom
- Ketika pemain Anda menekan thumbnail untuk membuat gestur, kirim ID gestur ke server menggunakan room.Send().
- Ketika Anda membatalkan gestur, proses untuk mengirim informasi bahwa Anda telah membatalkan.
- Saat menerima informasi gestur dari klien lain dari server: "OnChangeGesture" Pesan Ruang dikirim ke this.room.AddMessageHandler() dalam Start()
- Sinkronisasi dicapai dengan memiliki ID sesi dan ID gestur dalam pesan "OnChangeGesture" dan membuat pemain yang sesuai memainkan gestur tersebut.
import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
import { LocalPlayer, SpawnInfo, ZepetoCharacter, ZepetoPlayers } from 'ZEPETO.Character.Controller';
import { OfficialContentType, WorldService, ZepetoWorldContent, Content, ZepetoWorldMultiplay } from 'ZEPETO.World';
import { RawImage, Text, Button } from 'UnityEngine.UI';
import { GameObject, Texture2D, Transform, WaitUntil } from 'UnityEngine';
import Thumbnail from './Thumbnail';
import { Room, RoomData } from 'ZEPETO.Multiplay';
interface PlayerGestureInfo {
sessionId: string,
gestureId: string
}
const CancelMotion = "" as const;
export default class GestureLoaderMultiPlay extends ZepetoScriptBehaviour {
public multiplay: ZepetoWorldMultiplay;
@HideInInspector() public contents: Content[] = [];
@HideInInspector() public thumbnails: GameObject[] = [];
@SerializeField() private _count: number = 50;
@SerializeField() private _contentsParent: Transform;
@SerializeField() private _prefThumb: GameObject;
private _myCharacter: ZepetoCharacter;
private _room: Room;
private _contentsMap: Map<string, Content> = new Map<string, Content>();
Start() {
// Membuat Karakter
ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
this._myCharacter = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character;
// Untuk mengambil thumbnail dengan karakter saya, Anda perlu meminta konten setelah karakter dibuat.
this.ContentRequest();
});
// Untuk MultiPlay
this.multiplay.RoomCreated += (room: Room) => {
this._room = room;
// Menerima informasi gerakan pengguna dari server
this._room.AddMessageHandler("OnChangeGesture", (message: PlayerGestureInfo) => {
let playerGestureInfo: PlayerGestureInfo = {
sessionId: message.sessionId,
gestureId: message.gestureId
};
this.LoadAnimation(playerGestureInfo);
});
};
}
// 1. Menerima konten dari server
private ContentRequest(){
// Semua Tipe Permintaan
ZepetoWorldContent.RequestOfficialContentList(OfficialContentType.All, contents => {
this.contents = contents;
for (let i = 0; i < this._count; i++) {
if (!this.contents[i].IsDownloadedThumbnail) {
// Mengambil foto thumbnail menggunakan karakter saya
this.contents[i].DownloadThumbnail(() =>{
this.CreateThumbnailObjcet(this.contents[i]);
});
} else {
this.CreateThumbnailObjcet(this.contents[i]);
}
}
});
}
// 2. Membuat Objek Thumbnail
private CreateThumbnailObjcet(content: Content) {
const newThumb: GameObject = GameObject.Instantiate(this._prefThumb, this._contentsParent) as GameObject;
newThumb.GetComponent<Thumbnail>().content = content;
// Membuat kamus untuk menemukan konten dengan Id konten
this._contentsMap.set(content.Id, content);
// Pendengar Tombol untuk setiap thumbnail
newThumb.GetComponent<Button>().onClick.AddListener(() => {
this.SendMyGesture(content.Id);
});
// daftar thumbnail
this.thumbnails.push(newThumb);
}
// Untuk MultiPlay
// Mengirim informasi gerakan yang diklik ke server
public SendMyGesture(gestureId) {
const data = new RoomData();
data.Add("gestureId", gestureId);
this._room.Send("OnChangeGesture", data.GetObject());
}
// 3. Memuat Animasi
private LoadAnimation(playerGestureInfo: PlayerGestureInfo){
if (!ZepetoPlayers.instance.HasPlayer(playerGestureInfo.sessionId)) {
console.log("Pemain tidak ada");
return;
}
const zepetoPlayer = ZepetoPlayers.instance.GetPlayer(playerGestureInfo.sessionId).character;
if (playerGestureInfo.gestureId == CancelMotion) {
zepetoPlayer.CancelGesture();
return;
}
else if(!this._contentsMap.has(playerGestureInfo.gestureId)) {
console.log("Sumber daya belum dimuat");
return;
}
const content = this._contentsMap.get(playerGestureInfo.gestureId);
// Verifikasi pemuatan animasi
if (!content.IsDownloadedAnimation) {
// Jika animasi belum diunduh, unduh itu.
content.DownloadAnimation(() => {
// mainkan klip animasi
zepetoPlayer.SetGesture(content.AnimationClip);
});
} else {
zepetoPlayer.SetGesture(content.AnimationClip);
}
}
}
- Setelah menyelesaikan penulisan skrip, Inspektur akan menetapkan objek tambahan ke Multiplay dengan komponen Multiplay Zepeto World.


UIController - Multiplay
- Secara default, skrip yang diimplementasikan dalam kode klien permainan tunggal ditulis dengan cara yang sama.
- Perbedaannya dari kode klien permainan tunggal adalah fungsi kustom StopGesture().
- Panggil fungsi kustom SendMyGesture() di dalam GestureLoaderMultiplay.
- Proses untuk mengirim informasi bahwa gestur telah dibatalkan.
import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
import { Button, RawImage, Text, Toggle } from 'UnityEngine.UI';
import { LocalPlayer, ZepetoCharacter, ZepetoPlayers, ZepetoScreenTouchpad } from 'ZEPETO.Character.Controller';
import { OfficialContentType, Content } from 'ZEPETO.World';
import { Object, GameObject, Transform } from 'UnityEngine';
import GestureLoaderMultiPlay from './GestureLoaderMultiPlay';
import Thumbnail from './Thumbnail';
const CancelMotion = "" as const;
export default class UIController extends ZepetoScriptBehaviour {
@SerializeField() private _closeButton : Button;
@SerializeField() private _typeToggleGroup : Toggle[];
private _gestureLodaer: GestureLoaderMultiPlay;
private _myCharacter: ZepetoCharacter;
Start() {
this._gestureLodaer = Object.FindObjectOfType<GestureLoaderMultiPlay>();
ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
this._myCharacter = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character;
// Jika mengklik touchpad, batalkan gerakan
Object.FindObjectOfType<ZepetoScreenTouchpad>().OnPointerDownEvent.AddListener(() => {
this.StopGesture();
});
// Jika mengklik tombol tutup, batalkan gerakan
this._closeButton.onClick.AddListener(() => {
this.StopGesture();
});
});
// Pendengar UI
this._typeToggleGroup[0].onValueChanged.AddListener(() => {
this.SetCategoryUI(OfficialContentType.All);
});
this._typeToggleGroup[1].onValueChanged.AddListener(() => {
this.SetCategoryUI(OfficialContentType.Gesture);
});
this._typeToggleGroup[2].onValueChanged.AddListener(() => {
this.SetCategoryUI(OfficialContentType.Pose);
});
}
// Set UI Toggle Kategori
private SetCategoryUI(category: OfficialContentType) {
if (category == OfficialContentType.All) {
this._gestureLodaer.thumbnails.forEach((Obj) => {
Obj.SetActive(true);
});
} else {
for (let i = 0; i < this._gestureLodaer.thumbnails.length; i++) {
const content = this._gestureLodaer.thumbnails[i].GetComponent<Thumbnail>().content;
if (content.Keywords.includes(category)) {
this._gestureLodaer.thumbnails[i].SetActive(true);
} else {
this._gestureLodaer.thumbnails[i].SetActive(false);
}
}
}
}
private StopGesture() {
this._gestureLodaer.SendMyGesture(CancelMotion);
}
}
LANGKAH 4-2 : Kode Server
- Kode server kemudian menyatakan antarmuka untuk berisi PlayerGestureInfo dengan cara yang sama.
- Kode server didasarkan pada kode server dalam Contoh Multiplay secara default.
- Ini membuat callback onMessage() yang mengirimkan informasi gestur ke klien lain ketika gestur berubah dalam onCreate().
import { Sandbox, SandboxOptions, SandboxPlayer } from 'ZEPETO.Multiplay';
import { Player, Transform, Vector3 } from 'ZEPETO.Multiplay.Schema';
// Definisikan antarmuka PlayerGestureInfo untuk mewakili informasi gerakan pemain.
interface PlayerGestureInfo {
sessionId: string,
gestureId: string
}
export default class extends Sandbox {
// Definisikan objek konstan `MESSAGE_TYPE` untuk menyimpan jenis pesan yang digunakan dalam skrip.
MESSAGE_TYPE = {
OnChangeGesture: "OnChangeGesture"
}
onCreate(options: SandboxOptions) {
// Dipanggil saat Ruangan dibuat.
// Tangani status atau inisialisasi data Ruangan.
this.onMessage("onChangedTransform", (client, message) => {
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;
player.transform = transform;
});
this.onMessage("onChangedState", (client, message) => {
const player = this.state.players.get(client.sessionId);
player.state = message.state;
player.subState = message.subState; // Pengontrol Karakter V2
});
// Ketika gerakan diubah,
this.onMessage<PlayerGestureInfo>(this.MESSAGE_TYPE.OnChangeGesture, (client, message) => {
let gestureInfo:PlayerGestureInfo = {
sessionId: client.sessionId,
gestureId: message.gestureId
};
// Kirim gerakan ke pemain lain kecuali klien
this.broadcast(this.MESSAGE_TYPE.OnChangeGesture, gestureInfo);
});
}
onJoin(client: SandboxPlayer) {
// Atur nilai awal setelah membuat objek pemain yang didefinisikan dalam schemas.json.
console.log(`[OnJoin] sessionId : ${client.sessionId}, userId : ${client.userId}`)
const player = new Player();
player.sessionId = client.sessionId;
if (client.userId) {
player.zepetoUserId = client.userId;
}
// Kelola objek Pemain menggunakan sessionId, nilai kunci unik dari objek klien.
// Klien dapat memeriksa informasi tentang objek pemain yang ditambahkan dengan menambahkan acara add_OnAdd ke objek pemain.
this.state.players.set(client.sessionId, player);
}
onLeave(client: SandboxPlayer, consented?: boolean) {
// Dengan mengatur allowReconnection, dimungkinkan untuk mempertahankan koneksi untuk sirkuit, tetapi segera membersihkan dalam panduan dasar.
// Klien dapat memeriksa informasi tentang objek pemain yang dihapus dengan menambahkan acara add_OnRemove ke objek pemain.
this.state.players.delete(client.sessionId);
}
}