创造你的世界
与物体互动
将车辆应用到ZEPETO角色
18 分
通过应用关于将物体附加到zepeto角色的指南,您可以实现像汽车、飞机、宠物等骑乘车辆,就像角色正在骑它们一样。 📘 请参考以下指南 \[ 将物体附加到zepeto角色 docid\ r6xczne z5w8uycbga18u ] 设置动画师 1\) 通过转到项目 > 创建 > 动画控制器来创建一个动画控制器,并将其重命名为vehiclezepetoanimator。 2\) 在动画师选项卡中,通过选择创建状态 > 空状态来创建一个空状态。 3\) 在检查器中适当地重命名,并将动画剪辑分配给运动。 要使用您所需的动画剪辑文件,请参考自定义动画指南。 📘 请参考以下指南 \[ 如何应用自定义动画 docid\ gvco8q0twgtebrfodorye ] 4\) 拖放 vehiclezepetoanimator 到 zepetoplayers 上以进行设置。 👍 提示 如果相机高度需要根据车辆的大小进行更改,您可以在 zepetoplayers 中预设相机 lookoffset 值。 示例代码 1\) 通过访问项目 > 创建 > zepeto > typescript 创建一个 typescript,并将其重命名为 ridevehicle。 2\) 编写如下所示的示例脚本。 请注意,此示例中的车辆变换值应调整以匹配实际应用时的车辆预制件。 import { zepetoscriptbehaviour } from 'zepeto script'; import { zepetocharacter, zepetoplayers } from 'zepeto character controller'; import { transform, animator, gameobject, humanbodybones, object, vector3, quaternion } from 'unityengine'; export default class ridevehicle extends zepetoscriptbehaviour { public vehicleprefab gameobject; public bodybone humanbodybones; private localcharacter zepetocharacter; private vehicle gameobject; start() { zepetoplayers instance onaddedlocalplayer addlistener(() => { // 找到本地玩家并将其设置为 localcharacter。 this localcharacter = zepetoplayers instance localplayer zepetoplayer character; // 获取 localcharacter 的动画组件。 const animator animator = this localcharacter zepetoanimator; // 获取附加对象的骨骼位置。 const bone transform = animator getbonetransform(this bodybone); // 创建车辆预制件。 this vehicle = object instantiate(this vehicleprefab, bone) as gameobject; // 设置车辆变换 this vehicle transform localposition = new vector3(0 5, 0,0); this vehicle transform localrotation = quaternion euler(0, 0,90); }); } } 3\) 完成脚本编写后,将脚本添加到场景中的gameobject。 4\) 在检查器中,分配车辆的预制资源和要附加的身体骨骼。 5\) 点击播放按钮,您将看到zepeto角色骑在车辆上。 👍 提示 您可以通过简单地更改车辆的预制件和角色的动画片段来创建各种车辆。 消费物品时大小变化的示例 这是一个有趣的应用示例:实现角色在骑乘车辆时消费物品时大小变化的内容。 1\) 在这个示例中,我们准备了两种类型的预制件,并将消费后增大尺寸的物品的标签设置为“增大”,将减小尺寸的物品的标签设置为“减小”。 2\) 为每个物品添加碰撞体,并确保勾选istrigger。 3\) 通过访问项目 > 创建 > zepeto > typescript 创建一个 typescript,并将其重命名为 changeobjectsize。 4\) 编写如下所示的示例脚本。 import { collider, gameobject, vector3 } from 'unityengine'; import { zepetoscriptbehaviour } from 'zepeto script'; export default class changeobjectsize extends zepetoscriptbehaviour { public vehicle gameobject; start() { } ontriggerenter(collider collider) { if (collider tag === "increase") { this gameobject transform localscale += new vector3(0 1, 0 1, 0 1); gameobject destroy(collider gameobject); } if (collider tag === "decrease") { const decreaseamount = new vector3(0 1, 0 1, 0 1); const newscale = this gameobject transform localscale decreaseamount; gameobject destroy(collider gameobject); // 异常处理:确保缩放不小于 (1, 1, 1) if (newscale x >= 1 && newscale y >= 1 && newscale z >= 1) { this gameobject transform localscale = newscale; } } } } 代码的关键部分是修改 localscale,以便在 zepeto 角色接触每个物品时改变其大小。 可以自由调整数字以改变大小 但要确保处理异常,以防缩放变小于 (1,1,1)。 5\) 此脚本应添加到运行时创建的 zepeto 角色上。 因此,请按如下方式修改附加车辆的 ridevehicle 脚本。 import { zepetoscriptbehaviour } from 'zepeto script'; import { zepetocharacter, zepetoplayers } from 'zepeto character controller'; import { transform, animator, gameobject, humanbodybones, object, vector3, quaternion } from 'unityengine'; import changeobjectsize from ' /changeobjectsize'; export default class ridevehicle extends zepetoscriptbehaviour { public vehicleprefab gameobject; public bodybone humanbodybones; private localcharacter zepetocharacter; private vehicle gameobject; start() { zepetoplayers instance onaddedlocalplayer addlistener(() => { // 找到本地玩家并将其设置为 localcharacter。 this localcharacter = zepetoplayers instance localplayer zepetoplayer character; // 获取 localcharacter 的动画组件。 const animator animator = this localcharacter zepetoanimator; // 获取附加对象的骨骼位置。 const bone transform = animator getbonetransform(this bodybone); // 创建车辆预制件。 this vehicle = object instantiate(this vehicleprefab, bone) as gameobject; // 设置车辆变换 this vehicle transform localposition = new vector3(0 5, 0,0); this vehicle transform localrotation = quaternion euler(0, 0,90); // 将脚本添加到 charactercontroller const sizescript = this localcharacter gameobject addcomponent\<changeobjectsize>(); // 将车辆添加到脚本的检查器中 sizescript vehicle = this vehicle; }); } } 已添加在运行时添加changeobjectsize脚本的代码。 6\) 点击播放按钮,您会看到每次消耗物品时角色的大小都会变化。 与车辆互动 通过应用互动指南,可以在与车辆互动后,在所需位置实现登车。 📘 请参考以下指南。 \[ 与物体互动 docid hohoqb4fwal8vvllryxw ] 设置 1\) 按照交互指南,在您的车辆预制件上设置 dockpoint 对象和 ui 预制件。 2\) 在 unity 编辑器中,确保顶部的变换小工具切换按钮设置为本地,并旋转它,使 z 轴(蓝色箭头)指向对象外部。 3\) 添加一个碰撞器组件并检查 istrigger 选项。 4\) 调整碰撞器的大小,以便玩家可以与对象进行交互的范围。 5\) 创建一个空对象作为 dockpoint 的子对象,方法是转到层级 > 创建空对象,并将其重命名为 iconpos。 6\) 以与对象交互指南相同的方式设置 preficoncanvas,然后将其制作成预制件。 7\) 额外步骤:创建一个下车按钮 通过转到层级 > ui > 按钮,创建一个作为车辆对象的子按钮,并将其重命名为下车按钮。 为车辆添加登车动画 当角色上车或下车时,他们需要一个自然的动画设置来匹配。 下面的指南将帮助您完成上车或下车所需的动画设置。 请参考关于应用自定义动画的指南,以将坐下动画状态添加到您的自定义动画器中。 📘 请参考以下指南。 \[ 如何应用自定义动画 docid\ gvco8q0twgtebrfodorye ] 1\) 右键单击添加的动画状态,单击制作过渡以创建从闲置到坐下的过渡,并从坐下到闲置的过渡。选择创建的过渡并取消选中“有退出时间”选项。 2\) 在自定义动画器 → 参数 → \[ + ],添加一个布尔条件并将其重命名为isriding。 3\) 对于从坐下到闲置状态的过渡,单击条件 → \[ + ] 并添加isriding条件,选项设置为false。 4\) 对于从闲置到坐下状态的过渡,单击条件 → \[ + ] 并添加isriding条件,选项设置为true。 脚本 编写interactionicon ts脚本,与交互指南中的脚本相同,当进入车辆预制件的触发区域时显示交互ui。 将编写的 interactionicon zepetoscript 添加到 dockpoint 对象,并在检查器中分配 pref icon canvas 和 icon position。 请参阅下面的 ridevehicleexample 以获取有关如何在与 ui 交互后登上车辆的示例代码。 import { animator, gameobject, humanbodybones, physics, transform, vector3, waitforendofframe } from 'unityengine'; import { zepetoscriptbehaviour } from 'zepeto script'; import { zepetoplayers, zepetocharacter, characterstatemachine } from "zepeto character controller"; import { button } from 'unityengine ui'; import interactionicon from ' /interactionicon'; export default class ridevehicleexample extends zepetoscriptbehaviour { @serializefield() private bodybone humanbodybones; public isriding bool; public getoffbtn button; public vehicleobj gameobject; private interactionicon interactionicon; private localcharacter zepetocharacter; private playersittingposition vector3; private animator animator; private start() { zepetoplayers instance onaddedlocalplayer addlistener(() => { this localcharacter = zepetoplayers instance localplayer zepetoplayer character; this animator = this localcharacter zepetoanimator; }); this interactionicon = this transform getcomponent\<interactionicon>(); this interactionicon onclickevent addlistener(() => { // 当交互图标被点击时,隐藏图标并执行交互 this interactionicon hideicon(); this dointeraction(); }); // 设置 getoffbtn(退出车辆的按钮)的点击事件。 this getoffbtn onclick addlistener(() => { if(this isriding) { this stopinteraction(); this interactionicon showicon(); } }); this getoffbtn gameobject setactive(false); } //执行骑乘逻辑的方法 private dointeraction() { // 设置 animator 的过渡值以切换当前动画状态到坐着状态。 this animator setbool("isriding", true); this startcoroutine(this snapbone()); // 为了修复当前动画,停用 animator。 this localcharacter statemachine constraintstateanimation = true; // 将车辆对象的父级设置为本地角色。 this vehicleobj transform parent = this localcharacter transform; // 激活 getoffbutton。 this getoffbtn gameobject setactive(true); this isriding = true; } private stopinteraction() { // 设置 animator 的过渡值以切换动画状态到闲置。 this animator setbool("isriding", false); // 再次激活 animator。 this localcharacter statemachine constraintstateanimation = false; this isriding = false; // 将车辆对象的父级设置为 null。 this vehicleobj transform parent = null; // 停用 getoffbutton。 this getoffbtn gameobject setactive(false); } // 用于将骨骼固定到车辆的协程 private snapbone() { const animator animator = this localcharacter zepetoanimator; const bone transform = animator getbonetransform(this bodybone); let idx = 0; while (true) { // 计算骨骼与角色位置之间的距离。 const distance = vector3 op subtraction(bone position, this localcharacter transform position); const newpos vector3 = vector3 op subtraction(this transform position, distance); // 更新玩家坐着的位置并设置角色的位置和旋转。 this playersittingposition = newpos; this localcharacter transform position = this playersittingposition; this localcharacter transform rotation = this transform rotation; yield new waitforendofframe(); idx++; // 在 5 帧动画期间校准位置。 if (idx > 5) { return; } } } } 脚本的流程如下: 开始() 当点击图标时,this interactionicon 被停用,并调用 dointeraction() 函数。 dointeraction() 设置动画师的过渡值以播放坐下动画。 启动 snap bone() 协程,将 zepeto 角色的 bodybone 附加到 targettransform。 使用函数 this localcharacter statemachine constraintstateanimation = true; 来禁用当前动画师的过渡,锁定当前播放的动画。 车辆对象的父级更改为 zepeto 角色。 右上角的下车按钮被激活。 停止交互() 设置动画师的过渡值以播放闲置动画。 重新启用动画师过渡,以便根据情况播放适当的动画。 将车辆对象的父级设置为 null。 停用下车按钮。 this getoffbtn onclick 调用 stopinteraction() 函数。 this interactionicon 被激活。 将编写的 ridevehicleexample zepetoscript 添加到 dockpoint,并在检查器中分配下车按钮和车辆预制件。 \[▶︎(播放)] 按下播放按钮尝试登上车辆。 结果屏幕 👍 提示 上述示例是一个不考虑多人同步的内容示例。 要实现多人同步,您需要同步信息,例如每个玩家骑乘的车辆,以及车辆的大小和位置,作为房间状态。