CRÉEZ VOTRE MONDE
Geste
32min
l'api zepetoworldcontent vous permet de définir des vignettes pour les catégories de gestes/poses souhaitées et d'activer des gestes/poses spécifiques lorsqu'une vignette est cliquée pour utiliser l'api zepetoworldcontent, vous devez écrire une instruction d'importation comme suit import { officialcontenttype, worldservice, zepetoworldcontent, content } from 'zepeto world'; les informations sur les variables membres et les fonctions de la classe content contenant des informations sur les gestes/poses sont les suivantes api description public get id() string identifiant unique de contenu public get title() string texte du titre de geste, pose \ la langue sera automatiquement traduite en fonction de la langue de l'appareil public get thumbnail() unityengine texture2d miniature 2d public get animationclip() unityengine animationclip clip d'animation de geste public get isdownloadedthumbnail() boolean fonction pour déterminer si vous avez déjà téléchargé cette miniature public get isdownloadedanimation() boolean fonction pour déterminer si vous avez déjà téléchargé ce clip d'animation public downloadanimation($complete system action)\ void une fonction de téléchargement de clip d'animation qui reçoit un rappel de complétion avec un facteur \ si isdownloadedanimation() est faux, implémentez downloadanimation() pour être appelé public downloadthumbnail($complete system action)\ void fonction pour télécharger des miniatures \ si isdownloadedthumbnail() est faux, implémentez downloadthumbnail() pour être appelé officialcontenttype enum type de contenu (world 1 9 0 et supérieur) \ geste = 2 \ pose = 4 \ selfie = 8 \ gesturegreeting = 16 \ gesturepose = 32 \ gestureaffirmation = 64 \ gesturedancing = 128 \ gesturedenial = 256 \ gestureetc = 512 \ tout = 14 vous pouvez utiliser la fonction existante, public downloadthumbnail($character zepeto character controller zepetocharacter, $complete system action)\ void , sans aucun problème de fonctionnalité cependant, comme elle n'accepte plus le personnage zepeto comme argument, veuillez utiliser la fonction nouvellement modifiée public downloadthumbnail($complete system action)\ void à la place étape 1 configurer l'interface utilisateur étape 1 1 créer un bouton de geste 1\) ajoutez hiérarchie > ui > canvas et définissez l'ordre de tri sur 2 pour éviter d'être obscurci par d'autres interfaces utilisateur 2\) ajouter hiérarchie > ui > bouton étape 1 2 organiser le panneau de geste 1\) ajouter hiérarchie > créer objet vide et le renommer panelparent 2\) ajouter hiérarchie > ui > panneau comme enfant de panelparent 3\) bouton de fermeture après avoir ajouté ui > bouton, ajoutez un événement onclick pour désactiver le panneau de geste 4\) bouton d'ouverture veuillez ajouter un événement onclick qui active le panneau de geste au bouton d'ouverture créé ci dessus 5\) ajoutez une image pour servir de zone de titre 6\) configurez une vue défilante pour afficher la miniature de geste ajoutez hiérarchie > ui > vue défilante cochez horizontal et désactivez l'image de la barre de défilement car vous n'utiliserez que des défilements verticaux et des défilements horizontaux ne seront pas nécessaires ajoutez une mise en page en grille au contenu dans la vue défilante pour aligner les miniatures en motif de grille ajoutez un ajusteur de taille de contenu pour rendre la taille de l'objet appropriée à la taille du contenu lorsque vous implémentez un script, vous devez définir le contenu dans la vue défilante comme le parent de la miniature de geste (afin que toute la zone soit reconnue et défilée) 7\) configurez des onglets par type de geste ajouter une hiérarchie > créer un objet vide en tant qu'enfant du panneau et le renommer en gesturetitle ceci est l'objet parent du bouton bascule ajouter une mise en page horizontale pour aligner les onglets horizontalement ajouter le composant toggle group 👍 pour configurer plus d'onglets, ajoutez une hiérarchie > ui > scroll view et cochez horizontal dans l'option scroll view 8\) ajoutez le texte à utiliser comme bouton bascule en tant qu'enfant de gesturetitle, et remplacez le par tout définit la couleur du texte en gris ajoutez le texte surligné qui sera affiché lorsqu'il est coché en tant qu'enfant du texte définissez le contenu de la police, la taille et l'épaisseur de la même manière, et définissez la couleur sur noir ajoutez le composant toggle spécifiez l'objet parent dans le groupe ajoutez le texte surligné que vous avez ajouté en tant qu'enfant à graphic vérifiez ison uniquement pour les composants toggle all qui seront affichés en premier créez à la fois les boutons bascule gesture et pose de la même manière étape 1 3 créer des préfabriqués de vignettes utilisez la méthode de création d'un bouton vignette en tant que préfab et générez le ensuite en tant qu'instance dans un script 1\) ajoutez ui > bouton en tant qu'enfant de contenu dans la vue défilante et renommez le préthumb 2\) veuillez changer le nom en thumb après avoir ajouté l'image brute cette image sera une vignette ajustez la taille en conséquence 3\) ajoutez du texte réglez la position pour centrer le bas de l'image ajustez la taille et l'épaisseur de l'écriture, et ajoutez le ajusteur de taille de contenu ajustement horizontal taille préférée ajustement vertical taille préférée 4\) si le réglage est fait, veuillez en faire un préfab et le mettre dans le dossier resources étape 1 4 vidéo de guide de configuration de l'interface utilisateur https //www youtube com/watch?v=v ias8t8wq0 https //www youtube com/watch?v=v ias8t8wq0 👍 les valeurs de taille et de position de l'interface utilisateur montrées dans la vidéo sont recommandées, mais vous pouvez les modifier selon vos souhaits ! une fois la configuration de l'interface utilisateur terminée, passez à la scriptage étape 2 écrire un script ce script est basé sur un jeu unique étape 2 1 miniature projet > créer > zepeto > typescript et renommez le en miniature écrivez un script d'exemple comme ci dessous ceci est un script qui organise les informations de contenu de geste (titre, image) dans l'interface utilisateur miniature 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; } } après avoir créé le script, ouvrez le prefab prethumb et ajoutez le script étape 2 2 gestureloader créer une hiérarchie > créer un objet vide et le renommer en gestureloader créer un projet > créer > zepeto > typescript et le renommer en gestureloader écrire un script d'exemple comme ci dessous 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() { // création d'un personnage zepetoplayers instance createplayerwithuserid(worldservice userid, new spawninfo(), true); zepetoplayers instance onaddedlocalplayer addlistener(() => { this mycharacter = zepetoplayers instance localplayer zepetoplayer character; // pour prendre une miniature avec mon personnage, vous devez demander le contenu après la création du personnage this contentrequest(); }); } // 1 recevoir le contenu du serveur private contentrequest() { // demande de tous les types zepetoworldcontent requestofficialcontentlist(officialcontenttype all, contents => { this contents = contents; for (let i = 0; i < this count; i++) { if (!this contents\[i] isdownloadedthumbnail) { // prendre une photo miniature en utilisant mon personnage this contents\[i] downloadthumbnail(() =>{ this createthumbnailobjcet(this contents\[i]); }); } else { this createthumbnailobjcet(this contents\[i]); } } }); } // 2 création d'objets miniature private createthumbnailobjcet(content content) { const newthumb gameobject = gameobject instantiate(this prefthumb, this contentsparent) as gameobject; newthumb getcomponent\<thumbnail>() content = content; // écouteur de bouton pour chaque miniature newthumb getcomponent\<button>() onclick addlistener(() => { this loadanimation(content); }); this thumbnails push(newthumb); } // 3 chargement de l'animation private loadanimation(content content) { // vérifier le chargement de l'animation if (!content isdownloadedanimation) { // si l'animation n'a pas été téléchargée, téléchargez la content downloadanimation(() => { // jouer le clip d'animation this mycharacter setgesture(content animationclip); }); } else { this mycharacter setgesture(content animationclip); } } } le compte est le nombre maximum de gestes à télécharger sur chaque onglet si vous le définissez à un nombre supérieur à 100, il peut y avoir des erreurs lors du processus de téléchargement de la miniature, donc veuillez le définir uniquement autant que nécessaire le script se déroule comme suit 1\) invoquez la fonction personnalisée contentsrequest() pour générer des vignettes après avoir chargé le personnage zepeto la fonction contentsrequest() reçoit des informations sur le contenu en séparant les gestes et les poses, respectivement s'il existe une vignette, elle est ignorée ; sinon, la vignette est récupérée les données de vignette récupérées sont stockées dans des listes respectives étape 2 3 uicontroller créer une hiérarchie > créer un objet vide et le renommer en uicontoller créer un projet > créer > zepeto > typescript et le renommer en uicontoller écrire un script d'exemple comme ci dessous 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; // si vous cliquez sur le pavé tactile, annulez le geste object findobjectoftype\<zepetoscreentouchpad>() onpointerdownevent addlistener(() => { this stopgesture(); }); // si vous cliquez sur le bouton de fermeture, annulez le geste this closebutton onclick addlistener(() => { this stopgesture(); }); }); // écouteur 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); }); } // catégorie 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(); } } le script se déroule comme suit touchez le pavé tactile ou le bouton de fermeture pour annuler la lecture en utilisant la fonction cancelgesture() appuyez sur l'onglet (bouton de basculement) pour invoquer la fonction personnalisée setcategoryui() la fonction setcategoryui() utilise les informations de contenu de geste dans chaque miniature pour les définir pour chaque catégorie correspondante activez si c'est un type applicable, et désactivez sinon après avoir terminé le script, assignez le bouton de fermeture, typetogglegroup à l'inspecteur l'entrée du type toggle group est le toggle qui est un enfant du toggle group dans le panneau de geste étape 3 exécuter ❗️ attention avant de jouer, désactivez panelparent afin que seul le bouton d'ouverture soit visible lors de la lecture étape 4 synchroniser les gestes multi joueurs dans le cas d'un multi joueur, un code de synchronisation doit être ajouté pour recevoir la valeur d'information de geste prise par un joueur particulier et l'appliquer à tous les joueurs accédant à la salle la clé est d'envoyer et de recevoir un message de salle entre le serveur et le client concernant quel joueur a effectué quel geste étape 4 1 code client miniature multijoueur écrivez le même script que celui implémenté dans le code client en mode solo miniature multijoueur 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 multijoueur par défaut, les scripts implémentés dans le code client en mode solo sont écrits de la même manière de plus, le client déclare l'interface pour contenir le playergestureinfo lors de l'envoi de vos informations au serveur voir sendmygesture() fonction personnalisée lorsque votre joueur appuie sur la miniature pour faire un geste, envoyez l'id du geste au serveur en utilisant room send() lorsque vous annulez un geste, traitez le pour envoyer l'information que vous avez annulé lors de la réception d'informations sur le geste d'un autre client depuis le serveur "onchangegesture" le message de la salle est envoyé à this room addmessagehandler() dans start() la synchronisation est réalisée en ayant l'id de session et l'id de geste dans le message "onchangegesture" et en faisant jouer le geste au joueur approprié 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() { // création d'un personnage zepetoplayers instance onaddedlocalplayer addlistener(() => { this mycharacter = zepetoplayers instance localplayer zepetoplayer character; // pour prendre une miniature avec mon personnage, vous devez demander le contenu après la création du personnage this contentrequest(); }); // pour multiplay this multiplay roomcreated += (room room) => { this room = room; // recevoir les informations de geste de l'utilisateur depuis le serveur this room addmessagehandler("onchangegesture", (message playergestureinfo) => { let playergestureinfo playergestureinfo = { sessionid message sessionid, gestureid message gestureid }; this loadanimation(playergestureinfo); }); }; } // 1 recevoir le contenu du serveur private contentrequest(){ // demande de tous les types zepetoworldcontent requestofficialcontentlist(officialcontenttype all, contents => { this contents = contents; for (let i = 0; i < this count; i++) { if (!this contents\[i] isdownloadedthumbnail) { // prendre une photo miniature avec mon personnage this contents\[i] downloadthumbnail(() =>{ this createthumbnailobjcet(this contents\[i]); }); } else { this createthumbnailobjcet(this contents\[i]); } } }); } // 2 création d'objets miniature private createthumbnailobjcet(content content) { const newthumb gameobject = gameobject instantiate(this prefthumb, this contentsparent) as gameobject; newthumb getcomponent\<thumbnail>() content = content; // créer un dictionnaire pour trouver le contenu avec un id de contenu this contentsmap set(content id, content); // écouteur de bouton pour chaque miniature newthumb getcomponent\<button>() onclick addlistener(() => { this sendmygesture(content id); }); // liste des miniatures this thumbnails push(newthumb); } // pour multiplay // envoyer les informations de geste cliqué au serveur public sendmygesture(gestureid) { const data = new roomdata(); data add("gestureid", gestureid); this room send("onchangegesture", data getobject()); } // 3 chargement de l'animation private loadanimation(playergestureinfo playergestureinfo){ if (!zepetoplayers instance hasplayer(playergestureinfo sessionid)) { console log("le joueur n'existe pas"); 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("ressource pas encore chargée"); return; } const content = this contentsmap get(playergestureinfo gestureid); // vérifier le chargement de l'animation if (!content isdownloadedanimation) { // si l'animation n'a pas été téléchargée, téléchargez la content downloadanimation(() => { // jouer le clip d'animation zepetoplayer setgesture(content animationclip); }); } else { zepetoplayer setgesture(content animationclip); } } } après avoir terminé le script, l'inspecteur assignera un objet supplémentaire à multiplay avec le composant multiplay du monde zepeto uicontroller multiplay par défaut, les scripts implémentés dans le code client en mode solo sont écrits de la même manière la différence avec le code client en mode solo est la fonction personnalisée stopgesture() invoquez une fonction personnalisée sendmygesture() dans le gestureloadermultiplay processus pour envoyer des informations indiquant que le geste a été annulé 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; // si vous cliquez sur le pavé tactile, annulez le geste object findobjectoftype\<zepetoscreentouchpad>() onpointerdownevent addlistener(() => { this stopgesture(); }); // si vous cliquez sur le bouton de fermeture, annulez le geste this closebutton onclick addlistener(() => { this stopgesture(); }); }); // écouteur 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); }); } // catégorie 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 gesturelodaer sendmygesture(cancelmotion); } } étape 4 2 code du serveur le code du serveur déclare ensuite que l'interface contient le playergestureinfo de la même manière le code du serveur est basé sur le code du serveur dans l'exemple multiplay par défaut il crée un rappel onmessage() qui envoie des informations de geste à d'autres clients lorsque un geste change dans oncreate() import { sandbox, sandboxoptions, sandboxplayer } from 'zepeto multiplay'; import { player, transform, vector3 } from 'zepeto multiplay schema'; // définir une interface playergestureinfo pour représenter les informations du geste d'un joueur interface playergestureinfo { sessionid string, gestureid string } export default class extends sandbox { // définir un objet constant `message type` pour stocker les types de messages utilisés dans le script message type = { onchangegesture "onchangegesture" } oncreate(options sandboxoptions) { // appelé lorsque la salle est créée // gérer l'état ou l'initialisation des données de la salle 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; // contrôleur de personnage v2 }); // lorsque le geste est changé, this onmessage\<playergestureinfo>(this message type onchangegesture, (client, message) => { let gestureinfo\ playergestureinfo = { sessionid client sessionid, gestureid message gestureid }; // envoyer les gestes aux autres joueurs sauf au client this broadcast(this message type onchangegesture, gestureinfo); }); } onjoin(client sandboxplayer) { // définir la valeur initiale après avoir créé l'objet joueur défini dans 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; } // 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é en ajoutant l'événement add onadd à l'objet players this state players set(client sessionid, player); } 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); } }