创造你的世界
玩家及角色:进阶

创建一个NPC

33
学习如何从zepeto角色创建npc。 应用为每个功能提供的示例脚本,将您选择的npc添加到您的世界中。 使用zepeto id创建npc。 npc的外观和穿着的物品将与输入的zepeto id相同。 建议您在创建npc之前,先设置具有特定外观的zepeto角色。 设置npc将要创建的位置对象 在您的场景中默认实现zepeto角色创建代码。 📘 请参考以下指南。 \[ 创建一个zepeto角色 docid\ x uqcezxzv rams18k0bt ] 创建层级 > 创建空对象并将其重命名为npc。 一个用于存储npc将要创建的位置的对象。 设置位置、旋转。 编写npc创建脚本 1\) 创建项目 > 创建 > zepeto > typescript 并将其重命名为npccreator。 2\) 编写如下示例脚本。 import { zepetoscriptbehaviour } from 'zepeto script'; import { spawninfo, zepetocharacter, zepetocharactercreator } from 'zepeto character controller'; export default class npccreator extends zepetoscriptbehaviour { // npc的zepeto id public zepetoid string; // npc角色对象 private npc zepetocharacter; start() { // 创建spawninfo的新实例,并根据对象的变换设置其位置和旋转 const spawninfo = new spawninfo(); spawninfo position = this transform position; spawninfo rotation = this transform rotation; // 使用zepetocharactercreator通过zepeto id创建新角色,并将其分配给 npc变量 zepetocharactercreator createbyzepetoid(this zepetoid, spawninfo, (character zepetocharacter) => { this npc = character; }) } } 脚本的流程如下: start() 使用zepetocharactercreator createbyzepetoid()函数在npc对象位置创建npc,并将其保存在 npc中。 3\) 完成脚本编写后,将脚本添加到npc对象中。 4\) 在检查器中分配 zepeto id。 zepeto id npc 的 zepeto id。 5\) 按下播放按钮以执行,npc 将被创建。 6\) 以相同的方式添加 npc 位置对象,并添加 npc 脚本以轻松创建多个 npc。 标记 npc 您可以使用名称标签标记您的 npc,以将其与玩家区分开。 创建名称标签画布预制件 1\) 创建层级 > ui > 画布,并将其重命名为 prefnametagcanvas。 将渲染模式设置为世界空间。 2\) 创建层级 > ui > 文本,作为 prefnametagcanvas 的子项,并将其重命名为 nametagtext。 表示名称的文本。 添加一个内容大小适配器组件,使文本大小合适。 3\) 完成后,将其拖到项目窗口以使其成为预制件,然后删除仍在高亮显示的 prefnametagcanvas。 创建 npc 名称标签脚本 1\) 创建一个项目 > 创建 > zepeto > typescript,并将其重命名为 npccreatorwithnametag。 2\) 编写如下所示的示例脚本。 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 { // npc的zepeto id public zepetoid string; // 在名字标签中显示的名称 public nametag string; // 名字标签画布游戏对象的预制件 public nametagprefab gameobject; // 名字标签画布游戏对象的y轴偏移值 public nametagyoffset number; // npc角色对象 private npc zepetocharacter; // 名字标签画布游戏对象 private npcnametagobject gameobject; // 名字标签画布游戏对象中的文本 private npcnametagtext text; // 名字标签画布 private canvas canvas; // 世界相机 private cachedworldcamera camera; start() { // 创建spawninfo的新实例,并根据对象的变换设置其位置和旋转 const spawninfo = new spawninfo(); spawninfo position = this transform position; spawninfo rotation = this transform rotation; // 使用zepetocharactercreator通过zepeto id创建新角色并将其分配给 npc变量 zepetocharactercreator createbyzepetoid(this zepetoid, spawninfo, (character zepetocharacter) => { this npc = character; // 设置名字标签 this setnametag(); }) } // 设置名字标签 setnametag() { // 动态创建名字标签画布游戏对象 this npcnametagobject = object instantiate(this nametagprefab) as gameobject; // 将名字标签画布游戏对象的父级变换设置为npc变换。 this npcnametagobject transform setparent(this npc transform); // 将名字标签画布游戏对象的位置设置在npc的头顶上方 this npcnametagobject transform position = vector3 op addition(this npc getsocket(knowsockets head upper) position, new vector3(0, this nametagyoffset,0)); // 设置名字标签中的文本 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(); } } // 更新名字标签画布的旋转以面向相机 private updatecanvasrotation() { this canvas transform lookat(this cachedworldcamera transform); this canvas transform rotate(0, 180, 0); } } 脚本的流程如下: 开始() 调用 setnametag() 自定义函数。 setnametag() 动态生成 npc 的名称标签,并调整生成的名称标签在 npc 头顶的位置 设置名称标签内的文本。 更新() 调用 updatecanvasrotation() 自定义函数以旋转画布以匹配相机。 3\) 完成脚本编写后,将其添加到 npc 对象。 4\) 在检查器中,分配 zepeto id、名称标签、名称标签预制件和名称标签 y 偏移量。 名称标签:将在 npc 的名称标签上显示的名称。 名称标签预制件:名称标签画布预制件。 名称标签 y 偏移量:存储名称标签画布对象的 y 轴偏移值的变量。当您将名称标签放置在角色头顶时,可以调整角色与名称标签之间的距离。 5\) 按下播放按钮以执行,将创建带有名称标签的npc。 控制npc行为 您可以控制npc的动作。 跳跃 使用zepeto角色api使npc跳跃。 您可以使用 zepeto 角色 api 来实现更广泛的行为。 📘 请参考以下指南。 \[ zepeto角色 docid\ fjx8dujgdjma8i55zwctt ] 创建 npc 跳跃脚本 1\) 转到项目 > 创建 > zepeto > 创建 typescript 并将其重命名为 npcjump。 2\) 编写如下示例脚本。 import { zepetoscriptbehaviour } from 'zepeto script'; import { spawninfo, zepetocharacter, zepetocharactercreator } from 'zepeto character controller'; import { waitforseconds } from 'unityengine'; export default class npcjump extends zepetoscriptbehaviour { // npc 的 zepeto id public zepetoid string; // npc 角色对象 private npc zepetocharacter; start() { // 创建 spawninfo 的新实例,并根据对象的变换设置其位置和旋转 const spawninfo = new spawninfo(); spawninfo position = this transform position; spawninfo rotation = this transform rotation; // 使用 zepetocharactercreator 通过 zepeto id 创建新角色,并将其分配给 npc 变量 zepetocharactercreator createbyzepetoid(this zepetoid, spawninfo, (character zepetocharacter) => { this npc = character; this startcoroutine(this jumpcoroutine()); }); } jumpcoroutine() { // 无限循环以持续 while (true) { // 调用 zepetocharacter 的 jump() 方法使其跳跃 this npc jump(); // 等待 5 秒 yield new waitforseconds(5); } } } 脚本的流程如下: 开始() 调用 jumpcoroutine() 协程。 jumpcoroutine() 调用 jump() 方法使 npc 角色每 5 秒跳一次。 3\) 完成脚本编写后,将脚本添加到 npc 对象。 4\) 按下播放按钮,npc 将会跳跃。 手势 使用动画控制器为npc实现手势。 您可以使用动画控制器实现更广泛的行为。 📘 unity 动画控制器 https //docs unity3d com/manual/class animatorcontroller html https //docs unity3d com/manual/class animatorcontroller html 准备您的动画剪辑 使用以下指南准备npc执行的手势动画剪辑。 📘 请参考以下指南。 \[ 是否使用zepeto角色动画 docid\ oy8qovruwnsk8zhs vr r ] \[ 如何应用自定义动画 docid\ gvco8q0twgtebrfodorye ] 创建动画师 1\) 项目 > 创建 > 创建动画控制器并将其重命名为npcanimatorcontroller。 2\) 在动画师标签上,创建状态 > 空。 3\) 在检查器中,适当地重命名并将动画剪辑分配给运动。 创建npc手势脚本 1\) 创建一个项目 > 创建 > zepeto > typescript 并将其重命名为 npcgesture。 2\) 编写如下示例脚本。 import { zepetoscriptbehaviour } from 'zepeto script'; import { spawninfo, zepetocharacter, zepetocharactercreator } from 'zepeto character controller'; import { animator, runtimeanimatorcontroller } from 'unityengine'; export default class npcgesture extends zepetoscriptbehaviour { // npc 的 zepeto id public zepetoid string; // npc 的 animator controller public npcanimator runtimeanimatorcontroller; // npc 角色对象 private npc zepetocharacter; start() { // 创建 spawninfo 的新实例,并根据对象的变换设置其位置和旋转 const spawninfo = new spawninfo(); spawninfo position = this transform position; spawninfo rotation = this transform rotation; // 使用 zepetocharactercreator 根据 zepeto id 创建新角色,并将其分配给 npc 变量 zepetocharactercreator createbyzepetoid(this zepetoid, spawninfo, (character zepetocharacter) => { this npc = character; // 从 npc 角色获取 animator 组件,并将其 runtimeanimatorcontroller 设置为 npcanimator this npc getcomponentinchildren\<animator>() runtimeanimatorcontroller = this npcanimator; }); } } 脚本的流程如下: start() 获取 npc 对象的 animator 组件,并将其设置为由 npcanimator 变量指定的 animator controller。 3\) 在您完成编写脚本后,将其添加到将要创建 npc 的位置对象中。 4\) 在检查器中,分配 zepeto id,npc 动画师。 npc 动画师:npc 的动画控制器。 5\) 按下播放按钮以运行它,您将看到 npc 做出手势。 6\) 你可以应用这个来创建除了手势和跳跃之外还可以执行更多动作的npc。 npc上方的对话气泡 你可以在npc的头上创建一个画布,显示图像或文本,并使其呈气泡状。 创建对话气泡画布预制件 1\) 创建一个层级 > ui > 画布,并将其重命名为 prefspeechbubblecanvas。 将渲染模式设置为世界空间。 2\) 创建一个层级 > ui > 图像,作为 prefspeechbubblecanvas 的子项,并将其重命名为 speechbubbleimage。 这是将作为对话气泡背景的图像。 3\) 创建层次结构 > ui > 将文本作为对话气泡图像的子项,并将其重命名为对话气泡文本。 这是对话气泡内的文本。 添加一个内容大小适配器组件,使文本大小合适。 4\) 完成后,将其拖到项目窗口以使其成为预制件,然后删除仍在高亮显示的prefspeechbubblecanvas。 创建npc对话气泡脚本 1\) 创建一个项目 > 创建 > zepeto > typescript,并将其重命名为npc对话气泡。 2\) 编写如下示例脚本。 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 { // npc 的 zepeto id public zepetoid string; // 要在对话框中显示的对话内容 public speechbubbletext string; // 对话框画布游戏对象的预制件 public speechbubbleprefab gameobject; // 对话框画布游戏对象的 y 轴偏移值 public speechbubbleyoffset number; // npc 角色对象 private npc zepetocharacter; // 对话框画布游戏对象 private speechbubbleobject gameobject; // 对话框画布游戏对象中的文本 private speechbubbletext text; // 对话框画布 private canvas canvas; // 世界相机 private cachedworldcamera camera; start() { // 创建 spawninfo 的新实例,并根据对象的变换设置其位置和旋转 const spawninfo = new spawninfo(); spawninfo position = this transform position; spawninfo rotation = this transform rotation; // 使用 zepetocharactercreator 根据 zepeto id 创建新角色,并将其分配给 npc 变量 zepetocharactercreator createbyzepetoid(this zepetoid, spawninfo, (character zepetocharacter) => { this npc = character; // 设置对话框 this setbubble(); }) } // 设置对话框 setbubble() { // 动态创建对话框画布游戏对象 this speechbubbleobject = object instantiate(this speechbubbleprefab) as gameobject; // 将对话框画布游戏对象的父级变换设置为 npc 的变换。 this speechbubbleobject transform setparent(this npc transform); // 设置对话框画布游戏对象在 npc 头部上方的位置 this speechbubbleobject transform position = vector3 op addition(this npc getsocket(knowsockets head upper) position, new vector3(0, this speechbubbleyoffset,0)); // 设置对话框中的文本 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; } // 打开对话框画布并设置文本 setbubbletext(bubbletext string) { this speechbubbleobject setactive(true); this speechbubbletext text = bubbletext; } private update() { if (this canvas != null) { this updatecanvasrotation(); } } // 更新对话框画布的旋转以面向相机 private updatecanvasrotation() { this canvas transform lookat(this cachedworldcamera transform); this canvas transform rotate(0, 180, 0); } } 脚本的流程如下: 开始() 调用 setbubble() 自定义函数。 setbubble() 创建一个对话气泡画布 (speechbubbleprefab),并将创建的对话气泡放置在 npc 的头上 调用 setbubbletext() 自定义函数以设置对话气泡内的文本。 setbubbletext() 激活 npc 的对话气泡画布 ( speechbubbleobject)。 在对话气泡内显示作为参数给定的字符串 (bubbletext)。 更新() 调用 updatecanvasrotation() 自定义函数以旋转画布以匹配相机。 3\) 在您完成编写脚本后,将其添加到 npc 将要创建的位置对象中。 4\) 在检查器中,分配 zepeto id、对话框文本、对话框预制件和对话框 y 偏移量。 对话框文本:此变量存储 npc 角色在对话框中将要说的对话。在我们的示例中,我们存储以下对话:"你好,世界"。 对话框预制件:此变量存储对话框画布游戏对象的预制件。 对话框 y 偏移量:此变量存储对话框画布游戏对象的 y 轴偏移值。这允许您在将对话框放置在角色头上时调整角色与对话框之间的距离。 5\) 按下播放按钮以执行,您将看到一个对话框漂浮在 npc 的头上。 与 npc 互动 通过与npc互动,您可以实现许多有趣的内容。 在本指南中,我们将使用一个示例来实现一个在接近npc时会变化的对话框。 设置碰撞体 1\) 为您的对象添加一个碰撞体组件,以便与npc互动并检查istrigger。 2\) 调整碰撞体的大小,以便玩家可以与npc互动。 创建 npc 交互脚本 1\) 创建项目 > 创建 > zepeto > typescript,并将其重命名为 npcinteraction。 2\) 编写如下示例脚本。 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 { // npc的zepeto id public zepetoid string; // 在对话框中显示的对话内容 public speechbubbletext string; public changedspeechbubbletext string; // 对话框画布游戏对象的预制件 public speechbubbleprefab gameobject; // 对话框画布游戏对象的y轴偏移值 public speechbubbleyoffset number; // 本地角色对象 private zepetocharacter zepetocharacter; // npc角色对象 private npc zepetocharacter; // 对话框画布游戏对象 private speechbubbleobject gameobject; // 对话框画布游戏对象中的文本 private speechbubbletext text; // 对话框画布 private canvas canvas; // 世界相机 private cachedworldcamera camera; start() { // 创建spawninfo的新实例,并根据对象的变换设置其位置和旋转 const spawninfo = new spawninfo(); spawninfo position = this transform position; spawninfo rotation = this transform rotation; // 使用zepetocharactercreator通过zepeto id创建新角色,并将其分配给 npc变量 zepetocharactercreator createbyzepetoid(this zepetoid, spawninfo, (character zepetocharacter) => { this npc = character; // 设置对话框 this setbubble(); }) zepetoplayers instance onaddedlocalplayer addlistener(() => { this zepetocharacter = zepetoplayers instance localplayer zepetoplayer character; }); } // 检查玩家角色是否进入碰撞体 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); } // 设置对话框 setbubble() { // 动态创建对话框画布游戏对象 this speechbubbleobject = object instantiate(this speechbubbleprefab) as gameobject; // 将对话框画布游戏对象的父级变换设置为npc的变换。 this speechbubbleobject transform setparent(this npc transform); // 设置对话框画布游戏对象在npc头部上方的位置 this speechbubbleobject transform position = vector3 op addition(this npc getsocket(knowsockets head upper) position, new vector3(0, this speechbubbleyoffset,0)); // 设置对话框中的文本 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; } // 打开对话框画布并设置文本 setbubbletext(bubbletext string) { this speechbubbleobject setactive(true); this speechbubbletext text = bubbletext; } private update() { if (this canvas != null) { this updatecanvasrotation(); } } // 更新对话框画布的旋转以面向相机 private updatecanvasrotation() { this canvas transform lookat(this cachedworldcamera transform); this canvas transform rotate(0, 180, 0); } } 脚本的流程如下: ontriggerenter(), ontriggerexit() 当触发器通过进入碰撞体区域被检测到时,调用 setbubbletext() 自定义函数将对话框内的文本设置为 changedspeechbubbletext。 当它离开碰撞体区域时,调用 setbubbletext() 自定义函数将对话框内的文本设置为 speechbubbletext。 3\) 在您完成编写脚本后,将其添加到 npc 将要创建的位置对象中。 4\) 在检查器中,分配 zepeto id、对话框文本、对话框预制件、对话框 y 偏移量和更改后的对话框。 对话框文本:此变量存储 npc 角色将在对话框中说的对话。在我们的示例中,我们存储以下对话:"你好,世界"。 对话框预制件:此变量存储对话框画布游戏对象的预制件。 对话框 y 偏移量:此变量存储对话框画布游戏对象的 y 轴偏移值。这使您可以在角色头上放置对话框时调整角色与对话框之间的距离。 更改后的对话框:存储当玩家进入 npc 的碰撞体时将在 npc 的对话框中显示的对话。 5\) 按下播放以执行,当玩家接近npc时,气泡中的文本将会改变。 应用npc交互 要创建对话格式,请使用面板创建ui。 以下是一个由面板和按钮组成的简单对话示例。 这是一个示例脚本,当与npc交互时打开对话框,并在每个按钮被按下时处理它们。 应用此内容以实现有趣的内容。 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; }); // 对话 选择是 this yesbutton onclick addlistener(() => { console log("是") this npcdialogcanvas setactive(false); }); // 对话 选择否 this nobutton onclick addlistener(() => { console log("否") this npcdialogcanvas setactive(false); }); } // 检查玩家角色是否进入碰撞体 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); } }