สร้างโลกของคุณเอง
ท่าทาง
31นาที
zepetoworldcontent api ช่วยให้คุณตั้งภาพขนาดย่อสำหรับหมวดหมู่ท่าทาง/ท่าทางที่ต้องการและเปิดใช้งานท่าทาง/ท่าทางเฉพาะเมื่อคลิกที่ภาพขนาดย่อ ในการใช้ zepetoworldcontent api คุณต้องเขียนคำสั่งนำเข้า ดังนี้ import { officialcontenttype, worldservice, zepetoworldcontent, content } from 'zepeto world'; ข้อมูลตัวแปรและฟังก์ชันของคลาส content ที่มีข้อมูลการเคลื่อนไหว/ท่าทางมีดังนี้ api คำอธิบาย public get id() string รหัสเฉพาะเนื้อหา public get title() string ข้อความชื่อท่าทาง \ ภาษา จะถูกแปลโดยอัตโนมัติตามภาษาของอุปกรณ์ public get thumbnail() unityengine texture2d ภาพขนาดย่อ 2d public get animationclip() unityengine animationclip คลิปอนิเมชันท่าทาง public get isdownloadedthumbnail() boolean ฟังก์ชันเพื่อตรวจสอบว่าคุณได้ดาวน์โหลดภาพขนาดย่อนี้แล้วหรือไม่ public get isdownloadedanimation() boolean ฟังก์ชันเพื่อตรวจสอบว่าคุณได้ดาวน์โหลดคลิปอนิเมชันนี้แล้วหรือไม่ public downloadanimation($complete system action)\ void ฟังก์ชันดาวน์โหลดคลิปอนิเมชันที่รับการเรียกกลับเมื่อเสร็จสิ้น \ หาก isdownloadedanimation() เป็น false ให้เรียกใช้ downloadanimation() public downloadthumbnail($complete system action)\ void ฟังก์ชันดาวน์โหลดภาพขนาดย่อ \ หาก isdownloadedthumbnail() เป็น false ให้เรียกใช้ downloadthumbnail() officialcontenttype enum ประเภทของเนื้อหา (world 1 9 0 ขึ้นไป) \ ท่าทาง = 2 \ ท่าทาง = 4 \ เซลฟี่ = 8 \ ท่าทางทักทาย = 16 \ ท่าทาง = 32 \ ท่าทางยืนยัน = 64 \ ท่าทางเต้น = 128 \ ท่าทางปฏิเสธ = 256 \ ท่าทางอื่น ๆ = 512 \ ทั้งหมด = 14 คุณสามารถใช้ฟังก์ชันที่มีอยู่แล้ว public downloadthumbnail($character zepeto character controller zepetocharacter, $complete system action)\ void , โดยไม่มีปัญหาเกี่ยวกับฟังก์ชันการทำงาน อย่างไรก็ตาม เนื่องจากมันไม่รับตัวละคร zepeto เป็นอาร์กิวเมนต์อีกต่อไป กรุณาใช้ฟังก์ชันที่แก้ไขใหม่ public downloadthumbnail($complete system action)\ void แทน ขั้นตอนที่ 1 ตั้งค่า ui ขั้นตอนที่ 1 1 สร้างปุ่มท่าทาง 1\) เพิ่ม hierarchy > ui > canvas และตั้งค่า sort order เป็น 2 เพื่อหลีกเลี่ยงการถูกบดบังโดย ui อื่น 2\) เพิ่มลำดับชั้น > ui > ปุ่ม ขั้นตอน 1 2 จัดระเบียบแผงท่าทาง 1\) เพิ่มลำดับชั้น > สร้างวัตถุว่างและเปลี่ยนชื่อเป็น panelparent 2\) เพิ่มลำดับชั้น > ui > แผงเป็นลูกของ panelparent 3\) ปุ่มปิด หลังจากเพิ่ม ui > ปุ่ม ให้เพิ่มเหตุการณ์ onclick เพื่อปิดแผงท่าทาง 4\) ปุ่มเปิด กรุณาเพิ่มเหตุการณ์ onclick ที่เปิดแผงท่าทางไปยังปุ่มเปิดที่สร้างขึ้นข้างต้น 5\) เพิ่มภาพเพื่อใช้เป็นพื้นที่ชื่อเรื่อง 6\) ตั้งค่ามุมมองเลื่อนเพื่อแสดงภาพขนาดย่อของท่าทาง เพิ่ม hierarchy > ui > scroll view ตรวจสอบ horizontal และปิดการใช้งานภาพแถบเลื่อนเนื่องจากคุณจะใช้เฉพาะการเลื่อนแนวตั้งและไม่ต้องการการเลื่อนแนวนอน เพิ่มเลย์เอาต์แบบกริดไปยังเนื้อหาใน scroll view เพื่อจัดเรียงภาพขนาดย่อในรูปแบบกริด เพิ่ม content size fitter เพื่อทำให้ขนาดของวัตถุเหมาะสมกับขนาดของเนื้อหา เมื่อคุณดำเนินการสคริปต์ คุณต้องตั้งค่าเนื้อหาใน scroll view เป็นผู้ปกครองของภาพขนาดย่อของท่าทาง (เพื่อให้พื้นที่ทั้งหมดถูกจดจำและเลื่อน) 7\) ตั้งค่าแท็บตามประเภทท่าทาง เพิ่มลำดับชั้น > สร้างวัตถุว่างเป็นลูกของแผงและเปลี่ยนชื่อเป็น gesturetitle นี่คือวัตถุหลักของปุ่มสลับ เพิ่มเลย์เอาต์แนวนอนเพื่อจัดเรียงแท็บในแนวนอน เพิ่มส่วนประกอบกลุ่มสลับ 👍 ในการกำหนดค่าแท็บเพิ่มเติม ให้เพิ่มลำดับชั้น > ui > scroll view และตรวจสอบแนวนอนในตัวเลือก scroll view 8\) เพิ่มข้อความที่จะใช้เป็นปุ่มสลับเป็นลูกของ gesturetitle และแทนที่ด้วย all ตั้งค่าสีของข้อความเป็นสีเทา เพิ่มข้อความที่เน้นซึ่งจะแสดงเมื่อถูกเลือกเป็นลูกของข้อความ ตั้งค่าขนาดและความหนาของฟอนต์ให้เหมือนกัน และตั้งค่าสีเป็นสีดำ เพิ่มส่วนประกอบ toggle ระบุวัตถุหลักในกลุ่ม เพิ่มข้อความที่เน้นซึ่งคุณได้เพิ่มเป็นลูกให้กับ graphic ตรวจสอบ ison เฉพาะสำหรับส่วนประกอบ toggle ทั้งหมดที่จะถูกแสดงก่อน สร้างปุ่มสลับ gesture และ pose ทั้งสองในลักษณะเดียวกัน ขั้นตอน 1 3 สร้างพรีแฟบภาพขนาดย่อ ใช้วิธีการสร้างปุ่มภาพขนาดย่อเป็นพรีแฟบและจากนั้นสร้างเป็นอินสแตนซ์ในสคริปต์ 1\) เพิ่ม ui > ปุ่ม เป็นลูกของเนื้อหาใน scroll view และเปลี่ยนชื่อเป็น prethumb 2\) กรุณาเปลี่ยนชื่อเป็น thumb หลังจากเพิ่ม raw image ภาพนี้จะเป็นภาพขนาดย่อ ปรับขนาดให้เหมาะสม 3\) เพิ่มข้อความ ตั้งตำแหน่งให้กึ่งกลางด้านล่างของภาพ ปรับขนาดและความหนาของการเขียน และเพิ่ม content size fitter horizontal fit ขนาดที่ต้องการ vertical fit ขนาดที่ต้องการ 4\) หากการตั้งค่าเสร็จสิ้น กรุณาทำให้เป็น prefab และใส่ในโฟลเดอร์ resources ขั้นตอนที่ 1 4 วิดีโอแนะนำการตั้งค่า ui https //www youtube com/watch?v=v ias8t8wq0 https //www youtube com/watch?v=v ias8t8wq0 👍 ค่าขนาดและตำแหน่งของ ui ที่แสดงในวิดีโอเป็นค่าที่แนะนำ แต่คุณสามารถปรับเปลี่ยนให้เป็นค่าที่คุณต้องการได้! เมื่อการตั้งค่า ui เสร็จสิ้น ให้ดำเนินการไปที่การเขียนสคริปต์ ขั้นตอนที่ 2 เขียนสคริปต์ สคริปต์นี้อิงจากการเล่นแบบเดี่ยว ขั้นตอนที่ 2 1 รูปขนาดย่อ โปรเจกต์ > สร้าง > zepeto > typescript และเปลี่ยนชื่อเป็น รูปขนาดย่อ เขียนสคริปต์ตัวอย่างตามด้านล่าง นี่คือสคริปต์ที่จัดระเบียบข้อมูลเนื้อหาท่าทาง (ชื่อ, รูปภาพ) ลงใน 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; } } หลังจากสร้างสคริปต์แล้ว ให้เปิด prefab prethumb และเพิ่มสคริปต์เข้าไป ขั้นตอนที่ 2 2 gestureloader สร้างลำดับชั้น > สร้างวัตถุเปล่าและเปลี่ยนชื่อเป็น gestureloader สร้างโปรเจกต์ > สร้าง > zepeto > typescript และเปลี่ยนชื่อเป็น gestureloader เขียนสคริปต์ตัวอย่างตามด้านล่าง gestureloader 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() { // creating a character zepetoplayers instance createplayerwithuserid(worldservice userid, new spawninfo(), true); zepetoplayers instance onaddedlocalplayer addlistener(() => { this mycharacter = zepetoplayers instance localplayer zepetoplayer character; // in order to take a thumbnail with my character, you need to request the content after the character is created this contentrequest(); }); } // 1 receive content from the server private contentrequest() { // all type request zepetoworldcontent requestofficialcontentlist(officialcontenttype all, contents => { this contents = contents; for (let i = 0; i < this count; i++) { if (!this contents\[i] isdownloadedthumbnail) { // take a thumbnail photo using my character this contents\[i] downloadthumbnail(() =>{ this createthumbnailobjcet(this contents\[i]); }); } else { this createthumbnailobjcet(this contents\[i]); } } }); } // 2 creating thumbnail objects private createthumbnailobjcet(content content) { const newthumb gameobject = gameobject instantiate(this prefthumb, this contentsparent) as gameobject; newthumb getcomponent\<thumbnail>() content = content; // button listener for each thumbnail newthumb getcomponent\<button>() onclick addlistener(() => { this loadanimation(content); }); this thumbnails push(newthumb); } // 3 loading animation private loadanimation(content content) { // verify animation load if (!content isdownloadedanimation) { // if the animation has not been downloaded, download it content downloadanimation(() => { // play animation clip this mycharacter setgesture(content animationclip); }); } else { this mycharacter setgesture(content animationclip); } } } จำนวนคือจำนวนสูงสุดของท่าทางที่จะดาวน์โหลดในแต่ละแท็บ หากคุณตั้งค่าให้มากกว่า 100 อาจมีข้อผิดพลาดในระหว่างกระบวนการดาวน์โหลดภาพขนาดย่อ ดังนั้นโปรดตั้งค่าให้เพียงพอต่อความต้องการเท่านั้น สคริปต์มีลำดับการไหลดังนี้ 1\) เรียกใช้ฟังก์ชัน contentsrequest() ที่กำหนดเองเพื่อสร้างภาพขนาดย่อหลังจากโหลดตัวละคร zepeto ฟังก์ชัน contentsrequest() จะรับข้อมูลเนื้อหาโดยการแยกท่าทางและท่าทางออกจากกันตามลำดับ หากมีภาพขนาดย่อที่มีอยู่แล้ว จะถูกข้ามไป; มิฉะนั้น จะดึงภาพขนาดย่อมา ข้อมูลภาพขนาดย่อที่ดึงมาได้จะถูกเก็บไว้ในรายการที่เกี่ยวข้อง ขั้นตอน 2 3 uicontroller สร้าง hierarchy > สร้างวัตถุเปล่าและเปลี่ยนชื่อเป็น uicontoller สร้างโปรเจกต์ > สร้าง > zepeto > typescript และเปลี่ยนชื่อเป็น uicontoller เขียนสคริปต์ตัวอย่างตามด้านล่าง uicontroller 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; // if click the touchpad, cancel the gesture object findobjectoftype\<zepetoscreentouchpad>() onpointerdownevent addlistener(() => { this stopgesture(); }); // if click the close button, cancel the gesture this closebutton onclick addlistener(() => { this stopgesture(); }); }); // ui listener 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); }); } // category toggle ui set 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(); } } สคริปต์ทำงานดังนี้ แตะที่แผ่นสัมผัสหรือปุ่มปิดเพื่อยกเลิกการเล่นโดยใช้ฟังก์ชัน cancelgesture() แตะที่แท็บ (ปุ่มสลับ) เพื่อเรียกใช้ฟังก์ชัน setcategoryui() ที่กำหนดเอง ฟังก์ชัน setcategoryui() ใช้ข้อมูลเนื้อหาท่าทางในแต่ละภาพขนาดย่อเพื่อตั้งค่าสำหรับแต่ละหมวดหมู่ที่เกี่ยวข้อง เปิดใช้งานหากเป็นประเภทที่ใช้ได้ และปิดใช้งานหากไม่ใช่ หลังจากเสร็จสิ้นการเขียนสคริปต์ ให้กำหนดปุ่มปิดและ typetogglegroup ใน inspector การเข้าถึง type toggle group คือ toggle ที่เป็นลูกของ toggle group ในแผงการเคลื่อนไหว ขั้นตอนที่ 3 รัน ❗️ ระวัง ก่อนเล่น ให้ปิด panelparent เพื่อให้เห็นเฉพาะปุ่มเปิดเมื่อเล่นเท่านั้น ขั้นตอนที่ 4 ซิงโครไนซ์ท่าทางการเล่นหลายคน ในกรณีที่เล่นหลายคน ต้องเพิ่มรหัสซิงโครไนซ์ที่รับค่าข้อมูลท่าทางที่ผู้เล่นเฉพาะคนทำและนำไปใช้กับผู้เล่นทุกคนที่เข้าถึงห้อง กุญแจคือการส่งและรับข้อความห้องระหว่างเซิร์ฟเวอร์และไคลเอนต์เกี่ยวกับผู้เล่นคนไหนทำท่าทางไหน ขั้นตอน 4 1 รหัสลูกค้า ภาพขนาดย่อ หลายผู้เล่น เขียนสคริปต์เดียวกันกับที่ใช้ในรหัสลูกค้าแบบเล่นคนเดียว ภาพขนาดย่อ หลายผู้เล่น 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 หลายผู้เล่น โดยค่าเริ่มต้น สคริปต์ที่ใช้ในรหัสลูกค้าแบบเล่นคนเดียวจะเขียนเหมือนกัน นอกจากนี้ ลูกค้าจะประกาศอินเตอร์เฟซเพื่อให้มี playergestureinfo เมื่อส่งข้อมูลของคุณไปยังเซิร์ฟเวอร์ ดู sendmygesture() ฟังก์ชันที่กำหนดเอง เมื่อผู้เล่นของคุณกดที่ภาพขนาดย่อเพื่อทำท่าทาง ส่ง id ของท่าทางไปยังเซิร์ฟเวอร์โดยใช้ room send() เมื่อคุณยกเลิกท่าทาง ให้ประมวลผลเพื่อส่งข้อมูลว่าคุณได้ยกเลิกแล้ว เมื่อได้รับข้อมูลท่าทางจากลูกค้าอื่นจากเซิร์ฟเวอร์ "onchangegesture" ข้อความห้องจะถูกส่งไปยัง this room addmessagehandler() ภายใน start() การซิงโครไนซ์จะเกิดขึ้นโดยการมี id เซสชันและ id ท่าทางในข้อความ "onchangegesture" และทำให้ผู้เล่นที่เหมาะสมเล่นท่าทางนั้น 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() { // สร้างตัวละคร zepetoplayers instance onaddedlocalplayer addlistener(() => { this mycharacter = zepetoplayers instance localplayer zepetoplayer character; // เพื่อที่จะถ่ายภาพ thumbnail ด้วยตัวละครของฉัน คุณต้องขอเนื้อหาหลังจากที่ตัวละครถูกสร้างขึ้น this contentrequest(); }); // สำหรับ multiplay this multiplay roomcreated += (room room) => { this room = room; // รับข้อมูลท่าทางของผู้ใช้จากเซิร์ฟเวอร์ this room addmessagehandler("onchangegesture", (message playergestureinfo) => { let playergestureinfo playergestureinfo = { sessionid message sessionid, gestureid message gestureid }; this loadanimation(playergestureinfo); }); }; } // 1 รับเนื้อหาจากเซิร์ฟเวอร์ private contentrequest(){ // ขอทุกประเภท zepetoworldcontent requestofficialcontentlist(officialcontenttype all, contents => { this contents = contents; for (let i = 0; i < this count; i++) { if (!this contents\[i] isdownloadedthumbnail) { // ถ่ายภาพ thumbnail โดยใช้ตัวละครของฉัน this contents\[i] downloadthumbnail(() =>{ this createthumbnailobjcet(this contents\[i]); }); } else { this createthumbnailobjcet(this contents\[i]); } } }); } // 2 สร้างวัตถุ thumbnail private createthumbnailobjcet(content content) { const newthumb gameobject = gameobject instantiate(this prefthumb, this contentsparent) as gameobject; newthumb getcomponent\<thumbnail>() content = content; // สร้างพจนานุกรมเพื่อค้นหาเนื้อหาด้วย id ของเนื้อหา this contentsmap set(content id, content); // ตัวฟังปุ่มสำหรับแต่ละ thumbnail newthumb getcomponent\<button>() onclick addlistener(() => { this sendmygesture(content id); }); // รายการ thumbnail this thumbnails push(newthumb); } // สำหรับ multiplay // ส่งข้อมูลท่าทางที่คลิกไปยังเซิร์ฟเวอร์ public sendmygesture(gestureid) { const data = new roomdata(); data add("gestureid", gestureid); this room send("onchangegesture", data getobject()); } // 3 โหลดอนิเมชัน private loadanimation(playergestureinfo playergestureinfo){ if (!zepetoplayers instance hasplayer(playergestureinfo sessionid)) { console log("ผู้เล่นไม่มีอยู่"); 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("ทรัพยากรยังไม่ได้โหลด"); return; } const content = this contentsmap get(playergestureinfo gestureid); // ตรวจสอบการโหลดอนิเมชัน if (!content isdownloadedanimation) { // หากอนิเมชันยังไม่ได้ดาวน์โหลด ให้ดาวน์โหลดมัน content downloadanimation(() => { // เล่นคลิปอนิเมชัน zepetoplayer setgesture(content animationclip); }); } else { zepetoplayer setgesture(content animationclip); } } } หลังจากเสร็จสิ้นการเขียนสคริปต์ ผู้ตรวจสอบจะมอบวัตถุเพิ่มเติมให้กับ multiplay โดยใช้ส่วนประกอบ zepeto world multiplay uicontroller multiplay ตามค่าเริ่มต้น สคริปต์ที่ใช้ในโค้ดไคลเอนต์แบบเล่นคนเดียวจะเขียนเหมือนกันทั้งหมด ความแตกต่างจากโค้ดไคลเอนต์แบบเล่นคนเดียวคือฟังก์ชันที่กำหนดเอง stopgesture() เรียกใช้ฟังก์ชันที่กำหนดเอง sendmygesture() ภายใน gestureloadermultiplay กระบวนการส่งข้อมูลว่าท่าทางถูกยกเลิกแล้ว 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; // หากคลิกที่ touchpad ให้ยกเลิกท่าทาง object findobjectoftype\<zepetoscreentouchpad>() onpointerdownevent addlistener(() => { this stopgesture(); }); // หากคลิกที่ปุ่มปิด ให้ยกเลิกท่าทาง this closebutton onclick addlistener(() => { this stopgesture(); }); }); // ui listener 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); }); } // ตั้งค่า ui หมวดหมู่ 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 gesturelodaer sendmygesture(cancelmotion); } } ขั้นตอน 4 2 รหัสเซิร์ฟเวอร์ โค้ดเซิร์ฟเวอร์จะประกาศอินเทอร์เฟซเพื่อให้มี playergestureinfo ในลักษณะเดียวกัน โค้ดเซิร์ฟเวอร์อิงจากโค้ดเซิร์ฟเวอร์ใน multiplay sample โดยค่าเริ่มต้น มันสร้าง callback onmessage() ที่ส่งข้อมูลการเคลื่อนไหวไปยังลูกค้าอื่นเมื่อมีการเปลี่ยนแปลงการเคลื่อนไหวภายใน oncreate() import { sandbox, sandboxoptions, sandboxplayer } from 'zepeto multiplay'; import { player, transform, vector3 } from 'zepeto multiplay schema'; // กำหนดอินเตอร์เฟส playergestureinfo เพื่อแทนข้อมูลของท่าทางของผู้เล่น interface playergestureinfo { sessionid string, gestureid string } export default class extends sandbox { // กำหนดวัตถุคงที่ `message type` เพื่อเก็บประเภทข้อความที่ใช้ในสคริปต์ message type = { onchangegesture "onchangegesture" } oncreate(options sandboxoptions) { // ถูกเรียกเมื่อห้องถูกสร้าง // จัดการสถานะหรือการเริ่มต้นข้อมูลของห้อง 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; // ตัวควบคุมตัวละคร v2 }); // เมื่อท่าทางถูกเปลี่ยน this onmessage\<playergestureinfo>(this message type onchangegesture, (client, message) => { let gestureinfo\ playergestureinfo = { sessionid client sessionid, gestureid message gestureid }; // ส่งท่าทางไปยังผู้เล่นคนอื่นยกเว้นลูกค้า this broadcast(this message type onchangegesture, gestureinfo); }); } onjoin(client sandboxplayer) { // ตั้งค่าค่าตั้งต้นหลังจากสร้างวัตถุผู้เล่นที่กำหนดใน 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; } // จัดการวัตถุผู้เล่นโดยใช้ sessionid ซึ่งเป็นค่าคีย์ที่ไม่ซ้ำกันของวัตถุลูกค้า // ลูกค้าสามารถตรวจสอบข้อมูลเกี่ยวกับวัตถุผู้เล่นที่เพิ่มโดยการตั้งค่าโดยการเพิ่มเหตุการณ์ add onadd ไปยังวัตถุผู้เล่น this state players set(client sessionid, player); } onleave(client sandboxplayer, consented? boolean) { // โดยการตั้งค่า allowreconnection จะสามารถรักษาการเชื่อมต่อสำหรับวงจรได้ แต่ทำความสะอาดทันทีในคู่มือพื้นฐาน // ลูกค้าสามารถตรวจสอบข้อมูลเกี่ยวกับวัตถุผู้เล่นที่ถูกลบโดยการเพิ่มเหตุการณ์ add onremove ไปยังวัตถุผู้เล่น this state players delete(client sessionid); } }