CREATE YOUR WORLD
Players & Characters: Advanced
Creating an NPC
36min
learn how to create npcs from zepeto characters apply the sample scripts provided for each feature to add the npc of your choice to your world create an npc using a zepeto id the npc's appearance and items worn will be the same as the zepeto id entered it is recommended that you set up a zepeto character with a specific appearance before creating an npc setting the location object where the npc will be created implement the zepeto character creation code in your scene by default 📘 please refer to the following guide \[ creating a zepeto character docid k4o tkiw83wg jhy0isa ] create hierarchy > create empty object and rename it to npc an object to store the location where the npc will be created set the position, rotation writing an npc creation script 1\) create project > create > zepeto > typescript and rename it to npccreator 2\) write a sample script like below import { zepetoscriptbehaviour } from 'zepeto script'; import { spawninfo, zepetocharacter, zepetocharactercreator } from 'zepeto character controller'; export default class npccreator extends zepetoscriptbehaviour { // zepeto id of the npc public zepetoid string; // npc character object private npc zepetocharacter; start() { // create a new instance of spawninfo and set its position and rotation based on the object's transform const spawninfo = new spawninfo(); spawninfo position = this transform position; spawninfo rotation = this transform rotation; // use zepetocharactercreator to create a new character by zepeto id and assign it to npc variable zepetocharactercreator createbyzepetoid(this zepetoid, spawninfo, (character zepetocharacter) => { this npc = character; }) } } the flow of the script is as follows start() create an npc in the npc object location using the zepetocharactercreator createbyzepetoid() function and save it in npc 3\) after you have finished writing the script, add the script to the npc object 4\) assign the zepeto id in the inspector zepeto id the zepeto id of the npc 5\) press the play button to execute and the npc will be created 6\) add an npc location object in the same way, and add an npc script to create multiple npcs easily labeling npc you can label your npc with name tags to distinguish them from players to create the name tag canvas prefab 1\) create a hierachy > ui > canvas and rename it prefnametagcanvas set the render mode to world space 2\) create hierarchy> ui > text as a child of prefnametagcanvas and rename it to nametagtext the text to represent the name add a content size fitter component to make the text the right size 3\) once you're done, drag it to the project window to make it a prefab, and then delete the prefnametagcanvas that's still in the highlighter creating npc name tag script 1\) create a project > create > zepeto > typescript and rename it to npccreatorwithnametag 2\) write a sample script as shown below import { zepetoscriptbehaviour } from 'zepeto script'; import { knowsockets, spawninfo, zepetocharacter, zepetocharactercreator } from 'zepeto character controller'; import { canvas, camera, vector3, object, gameobject } from 'unityengine'; import { text } from 'unityengine ui'; export default class npccreatorwithnametag extends zepetoscriptbehaviour { // zepeto id of the npc public zepetoid string; // name to be displayed in the name tag public nametag string; // prefab of the name tag canvas game object public nametagprefab gameobject; // y axis offset value of the name tag canvas game object public nametagyoffset number; // npc character object private npc zepetocharacter; // name tag canvas game object private npcnametagobject gameobject; // text inside the name tag canvas game object private npcnametagtext text; // name tag canvas private canvas canvas; // world camera private cachedworldcamera camera; start() { // create a new instance of spawninfo and set its position and rotation based on the object's transform const spawninfo = new spawninfo(); spawninfo position = this transform position; spawninfo rotation = this transform rotation; // use zepetocharactercreator to create a new character by zepeto id and assign it to npc variable zepetocharactercreator createbyzepetoid(this zepetoid, spawninfo, (character zepetocharacter) => { this npc = character; // set the name tag this setnametag(); }) } // set the name tag setnametag() { // dynamically create the name tag canvas game object this npcnametagobject = object instantiate(this nametagprefab) as gameobject; // set the parent of the name tag canvas game object transform to be the npc transform this npcnametagobject transform setparent(this npc transform); // set the position of the name tag canvas game object above the npc's head this npcnametagobject transform position = vector3 op addition(this npc getsocket(knowsockets head upper) position, new vector3(0, this nametagyoffset,0)); // set the text inside the name tag this npcnametagtext = this npcnametagobject getcomponentinchildren\<text>(); this npcnametagtext text = this nametag; this canvas = this npcnametagobject getcomponent\<canvas>(); this cachedworldcamera = object findobjectoftype\<camera>(); this canvas worldcamera = this cachedworldcamera; } private update() { if (this canvas != null) { this updatecanvasrotation(); } } // update the rotation of the name tag canvas to face the camera private updatecanvasrotation() { this canvas transform lookat(this cachedworldcamera transform); this canvas transform rotate(0, 180, 0); } } the flow of the script is as follows start() call the setnametag() custom function setnametag() dynamically generates a name tag for the npc and adjusts the position of the generated name tag above the npc's head set the text inside the name tag update() call the updatecanvasrotation() custom function to rotate the canvas to match the camera 3\) after you have finished writing the script, add it to the npc object 4\) in the inspector, assign the zepeto id, name tag, name tag prefab, and name tag y offset name tag the name that will appear on the npc's name tag name tag prefab the name tag canvas prefab name tag y offset a variable that stores the y axis offset value for the name tag canvas object when you place the name tag above the character's head, you can adjust the distance between the character and the name tag 5\) press the play button to execute, and the npc with the name tag will be created controlling npc behavior you can control the actions of npc jumping use the zepeto character api to make the npc jump you can use the zepeto character api to implement a wider range of behaviors 📘 please refer to the following guide \[ zepeto character docid 1sjftquomtcxfkg3tjh g ] creating an npc jump script 1\) go to project > create > zepeto > create typescript and rename it to npcjump 2\) write a sample script as shown below import { zepetoscriptbehaviour } from 'zepeto script'; import { spawninfo, zepetocharacter, zepetocharactercreator } from 'zepeto character controller'; import { waitforseconds } from 'unityengine'; export default class npcjump extends zepetoscriptbehaviour { // zepeto id of the npc public zepetoid string; // npc character object private npc zepetocharacter; start() { // create a new instance of spawninfo and set its position and rotation based on the object's transform const spawninfo = new spawninfo(); spawninfo position = this transform position; spawninfo rotation = this transform rotation; // use zepetocharactercreator to create a new character by zepeto id and assign it to npc variable zepetocharactercreator createbyzepetoid(this zepetoid, spawninfo, (character zepetocharacter) => { this npc = character; this startcoroutine(this jumpcoroutine()); }); } jumpcoroutine() { // infinite loop to continuously while (true) { // call the jump() method of the zepetocharacter to make it jump this npc jump(); // wait for 5 seconds yield new waitforseconds(5); } } } the flow of the script is as follows start() call the jumpcoroutine() coroutine jumpcoroutine() call the jump() method to make the npc character jump every 5 seconds 3\) after you have finished writing the script, add the script to the npc object 4\) press the play button and the npc will jump gesture use the animator controller to implement gestures for npc you can use the animator controller to implement a wider variety of behaviors 📘 unity animator controller https //docs unity3d com/manual/class animatorcontroller html https //docs unity3d com/manual/class animatorcontroller html preparing your animation clip use the following guide to prepare the gesture animation clip for your npc to perform 📘 please refer to the following guide \[ whether to use zepeto character animation docid\ ahh0r8pikezml5up q4dc ] \[ how to apply custom animation docid\ fgnaprjtltzzp5pj6sn4x ] creating an animator 1\) project > create > create animator controller and rename it to npcanimatorcontroller 2\) on the animator tab, create state > empty 3\) in the inspector, rename it appropriately and assign the animation clip to motion creating an npc gesture script 1\) create a project > create > zepeto > typescript and rename it to npcgesture 2\) write a sample script as shown below import { zepetoscriptbehaviour } from 'zepeto script'; import { spawninfo, zepetocharacter, zepetocharactercreator } from 'zepeto character controller'; import { animator, runtimeanimatorcontroller } from 'unityengine'; export default class npcgesture extends zepetoscriptbehaviour { // the zepeto id of the npc public zepetoid string; // the animator controller of the npc public npcanimator runtimeanimatorcontroller; // npc character object private npc zepetocharacter; start() { // create a new instance of spawninfo and set its position and rotation based on the object's transform const spawninfo = new spawninfo(); spawninfo position = this transform position; spawninfo rotation = this transform rotation; // use zepetocharactercreator to create a new character by zepeto id and assign it to npc variable zepetocharactercreator createbyzepetoid(this zepetoid, spawninfo, (character zepetocharacter) => { this npc = character; // get the animator component from the npc character and set its runtimeanimatorcontroller to npcanimator this npc getcomponentinchildren\<animator>() runtimeanimatorcontroller = this npcanimator; }); } } the flow of the script is as follows start() get the animator component of the npc object and set it to the animator controller specified by the npcanimator variable 3\) after you finish writing the script, add it to the location object where the npc will be created 4\) in the inspector, assign the zepeto id, npc animator npc animator the npc's animation controller 5\) press the play button to run it and you'll see the npc make a gesture 6\) you can apply this to create npcs that do more actions besides gestures and jumps speech bubbles over npc you can create a canvas above an npc's head, display an image or text, and make it bubble creating a speech bubble canvas prefab 1\) create a hierarchy> ui > canvas and rename it to prefspeechbubblecanvas set the render mode to world space 2\) create a hierarchy> ui > image as a child of prefspeechbubblecanvas and rename it to speechbubbleimage this is the image that will be the background of the speech bubble 3\) create hierarchy> ui > text as a child of speeachbubbleimage and rename it to speeachbubbletext this is the text inside the speech bubble add a content size fitter component to make the text the right size 4\) once you're done, drag it to the project window to make it a prefab, and then delete the prefspeechbubblecanvas that is still in the highlight creating npc speech bubble script 1\) create a project > create > zepeto > typescript and rename it to npcspeechbubble 2\) write a sample script as shown below import { zepetoscriptbehaviour } from 'zepeto script'; import { knowsockets, spawninfo, zepetocharacter, zepetocharactercreator } from 'zepeto character controller'; import { canvas, camera, vector3, object, gameobject } from 'unityengine'; import { text } from 'unityengine ui'; export default class npcspeechbubble extends zepetoscriptbehaviour { // zepeto id of the npc public zepetoid string; // dialogue content to be displayed in the speech bubble public speechbubbletext string; // prefab of the speech bubble canvas game object public speechbubbleprefab gameobject; // y axis offset value of the speech bubble canvas game object public speechbubbleyoffset number; // npc character object private npc zepetocharacter; // speech bubble canvas game object private speechbubbleobject gameobject; // text inside the speech bubble canvas game object private speechbubbletext text; // speech bubble canvas private canvas canvas; // world camera private cachedworldcamera camera; start() { // create a new instance of spawninfo and set its position and rotation based on the object's transform const spawninfo = new spawninfo(); spawninfo position = this transform position; spawninfo rotation = this transform rotation; // use zepetocharactercreator to create a new character by zepeto id and assign it to npc variable zepetocharactercreator createbyzepetoid(this zepetoid, spawninfo, (character zepetocharacter) => { this npc = character; // set the speech bubble this setbubble(); }) } // set the speech bubble setbubble() { // dynamically create the speech bubble canvas game object this speechbubbleobject = object instantiate(this speechbubbleprefab) as gameobject; // set the parent of the speech bubble canvas game object transform to be the npc transform this speechbubbleobject transform setparent(this npc transform); // set the position of the speech bubble canvas game object above the npc's head this speechbubbleobject transform position = vector3 op addition(this npc getsocket(knowsockets head upper) position, new vector3(0, this speechbubbleyoffset,0)); // set the text inside the speech bubble this speechbubbletext = this speechbubbleobject getcomponentinchildren\<text>(); this setbubbletext(this speechbubbletext); this canvas = this speechbubbleobject getcomponent\<canvas>(); this cachedworldcamera = object findobjectoftype\<camera>(); this canvas worldcamera = this cachedworldcamera; } // open the speech bubble canvas and set the text setbubbletext(bubbletext string) { this speechbubbleobject setactive(true); this speechbubbletext text = bubbletext; } private update() { if (this canvas != null) { this updatecanvasrotation(); } } // update the rotation of the speech bubble canvas to face the camera private updatecanvasrotation() { this canvas transform lookat(this cachedworldcamera transform); this canvas transform rotate(0, 180, 0); } } the flow of the script is as follows start() call the setbubble() custom function setbubble() create a speech bubble canvas (speechbubbleprefab) and position the created speech bubble above the npc's head call the setbubbletext() custom function to set the text inside the speech bubble setbubbletext() activates the npc's speech bubble canvas ( speechbubbleobject) displays the string given as a parameter (bubbletext) inside the speech bubble update() call the updatecanvasrotation() custom function to rotate the canvas to match the camera 3\) after you have finished writing the script, add it to the location object where the npc will be created 4\) in the inspector, assign the zepeto id, speech bubble text, speech bubble prefab, and speech bubble y offset speech bubble text this variable stores the dialog that the npc character will say in the speech bubble in our example, we store the following dialog "hello world" speech bubble prefab this variable stores the prefab for the speech bubble canvas gameobject speech bubble y offset this variable stores the y axis offset value for the speech bubble canvas gameobject this allows you to adjust the distance between the character and the speech bubble when you place the speech bubble above the character's head 5\) press the play button to execute, and you will see a speech bubble floating above the npc's head interacting with npc you can implement a lot of fun content by interacting with npcs in this guide, we will use an example to implement a speech bubble that changes when an npc is approached setting up the collider 1\) add a collider component to your object to interact with the npc and check istrigger 2\) resize the collider to the extent that the player can interact with the npc creating an npc interaction script 1\) create project > create > zepeto > typescript and rename it to npcinteraction 2\) write a sample script as shown below import { zepetoscriptbehaviour } from 'zepeto script'; import { knowsockets, spawninfo, zepetocharacter, zepetocharactercreator, zepetoplayers } from 'zepeto character controller'; import { canvas, camera, vector3, object, gameobject, collider } from 'unityengine'; import { text } from 'unityengine ui'; export default class npcinteraction extends zepetoscriptbehaviour { // zepeto id of the npc public zepetoid string; // dialogue content to be displayed in the speech bubble public speechbubbletext string; public changedspeechbubbletext string; // prefab of the speech bubble canvas game object public speechbubbleprefab gameobject; // y axis offset value of the speech bubble canvas game object public speechbubbleyoffset number; // local character object private zepetocharacter zepetocharacter; // npc character object private npc zepetocharacter; // speech bubble canvas game object private speechbubbleobject gameobject; // text inside the speech bubble canvas game object private speechbubbletext text; // speech bubble canvas private canvas canvas; // world camera private cachedworldcamera camera; start() { // create a new instance of spawninfo and set its position and rotation based on the object's transform const spawninfo = new spawninfo(); spawninfo position = this transform position; spawninfo rotation = this transform rotation; // use zepetocharactercreator to create a new character by zepeto id and assign it to npc variable zepetocharactercreator createbyzepetoid(this zepetoid, spawninfo, (character zepetocharacter) => { this npc = character; // set the speech bubble this setbubble(); }) zepetoplayers instance onaddedlocalplayer addlistener(() => { this zepetocharacter = zepetoplayers instance localplayer zepetoplayer character; }); } // check if player character enter collider ontriggerenter(collider collider) { if (this zepetocharacter == null || collider gameobject != this zepetocharacter gameobject) { return; } this setbubbletext(this changedspeechbubbletext); } ontriggerexit(collider collider) { if (this zepetocharacter == null || collider gameobject != this zepetocharacter gameobject) { return; } this setbubbletext(this speechbubbletext); } // set the speech bubble setbubble() { // dynamically create the speech bubble canvas game object this speechbubbleobject = object instantiate(this speechbubbleprefab) as gameobject; // set the parent of the speech bubble canvas game object transform to be the npc transform this speechbubbleobject transform setparent(this npc transform); // set the position of the speech bubble canvas game object above the npc's head this speechbubbleobject transform position = vector3 op addition(this npc getsocket(knowsockets head upper) position, new vector3(0, this speechbubbleyoffset,0)); // set the text inside the speech bubble this speechbubbletext = this speechbubbleobject getcomponentinchildren\<text>(); this setbubbletext(this speechbubbletext); this canvas = this speechbubbleobject getcomponent\<canvas>(); this cachedworldcamera = object findobjectoftype\<camera>(); this canvas worldcamera = this cachedworldcamera; } // open the speech bubble canvas and set the text setbubbletext(bubbletext string) { this speechbubbleobject setactive(true); this speechbubbletext text = bubbletext; } private update() { if (this canvas != null) { this updatecanvasrotation(); } } // update the rotation of the speech bubble canvas to face the camera private updatecanvasrotation() { this canvas transform lookat(this cachedworldcamera transform); this canvas transform rotate(0, 180, 0); } } the flow of the script is as follows ontriggerenter(), ontriggerexit() when the trigger is detected by entering the collider area, call the setbubbletext() custom function to set the text inside the speech bubble to changedspeechbubbletext when it leaves the collider area, call the setbubbletext() custom function to set the text inside the speech bubble to speechbubbletext 3\) after you have finished writing the script, add it to the location object where the npc will be created 4\) in the inspector, assign the zepeto id, speech bubble text, speech bubble prefab, speech bubble y offset, and changed speech bubble speech bubble text this variable stores the dialog that the npc character will say in the speech bubble in our example, we store the following dialog "hello world" speech bubble prefab this variable stores the prefab for the speech bubble canvas gameobject speech bubble y offset this variable stores the y axis offset value for the speech bubble canvas gameobject this allows you to adjust the distance between the character and the speech bubble when placing the speech bubble above the character's head changed speech bubble stores the dialog that will be displayed in the npc's speech bubble when the player enters the npc's collider 5\) press play to execute, and when the player approaches the npc, the text in the speech bubble will change apply npc interaction to create a dialog format, create a ui using a panel the following is an example of a simple dialog composed of panels and buttons this is an example script that opens dialogs when interacting with npcs and processes them when each button is pressed apply this to implement interesting content import { gameobject, humanbodybones, object, collider } from 'unityengine'; import { zepetoscriptbehaviour } from 'zepeto script'; import { button } from 'unityengine ui'; import { zepetocharacter, zepetoplayers } from "zepeto character controller"; export default class npcdialoginteraction extends zepetoscriptbehaviour { public npcdialogcanvas gameobject; public yesbutton button; public nobutton button; private zepetocharacter zepetocharacter; start() { zepetoplayers instance onaddedlocalplayer addlistener(()=>{ this zepetocharacter = zepetoplayers instance localplayer zepetoplayer character; }); // dialog select yes this yesbutton onclick addlistener(() => { console log("yes") this npcdialogcanvas setactive(false); }); // dialog select no this nobutton onclick addlistener(() => { console log("no") this npcdialogcanvas setactive(false); }); } // check if player character enter collider ontriggerenter(collider collider) { if (this zepetocharacter == null || collider gameobject != this zepetocharacter gameobject) { return; } this npcdialogcanvas setactive(true); } ontriggerexit(collider collider) { if (this zepetocharacter == null || collider gameobject != this zepetocharacter gameobject) { return; } this npcdialogcanvas setactive(false); } }