---
title: 实现一个跟随角色的对象
slug: world-sdk-guide-ch/h9rfHXJmrB3xC21_oMPin
docTags: 
createdAt: 2024-09-02T08:34:13.135Z
---

通过使用 NavMeshAgent 组件，你可以创建一个跟随 ZEPETO 角色的 AI 对象。

在本指南中，我们将实现一个跟随你角色的 Pet 对象。

## 创建 Pet 对象

:::::WorkflowBlock
:::WorkflowBlockItem
**打开 Navigation (Obsolete) 窗口**

![](https://api.archbee.com/api/optimize/xv-TGeWVTX2GDZMFGOf1Y/ioeagnYkRZnNx3-Fh3DQH_image.png)

在 Unity 顶部菜单中点击 **Window > AI > Navigation (Obsolete)**，打开 Navigation (Obsolete) 窗口。
:::

::::WorkflowBlockItem
**定义 Pet 对象可以移动的区域**

::Image[]{src="https://api.archbee.com/api/optimize/xv-TGeWVTX2GDZMFGOf1Y/6Hnn9ZZKQBMr-JhQhFlt2_image.png" size="70" width="710" height="458" position="center" showCaption="false"}

在 Navigation (Obsolete) 窗口中，点击 Object 选项卡。在 Hierarchy 中选择需要加入 NavMesh 的地面、墙壁或障碍物，并添加到 Object 中。

- 这样可以让 Pet 对象识别哪些是可行走区域，哪些是障碍物。

请确保勾选了 **Navigation Static** 选项。

:::hint{type="info"}
✏️ 关于 NavMesh 的详细信息，请参阅以下视频。

::embed[]{url="https://www.youtube.com/watch?v=mP7ulMu5UkU"}
:::
::::

:::WorkflowBlockItem
**生成 NavMesh**

![](https://api.archbee.com/api/optimize/xv-TGeWVTX2GDZMFGOf1Y/Q-90_MdXrB1zN3pc8dzIj_image.png)

点击 **Bake** 选项卡，然后点击底部的 **Bake** 按钮以生成 NavMesh。
:::

::::WorkflowBlockItem
**添加 NavMeshAgent**

在 Hierarchy 中选择 Pet 对象，然后在 Inspector 中添加 **NavMeshAgent** 组件。

- 此处的 Agent 指的是通过 NavMesh 导航系统移动的 Pet 对象。

你可以调整 Agent 的大小、移动速度、旋转速度、加速度以及识别障碍物的高度等属性。

:::hint{type="info"}
✏️ 关于 NavMeshAgent 的更多信息，请参考以下[链接](https://docs.unity3d.com/kr/2021.3/Manual/class-NavMeshAgent.html)。
:::

![](https://api.archbee.com/api/optimize/xv-TGeWVTX2GDZMFGOf1Y/NWdi4SSnexNRcoVeE13jG_image.png)

在本示例中，我们将 NavMeshAgent 的 Stopping Distance 设置为 3，使 Pet 会在距离玩家 3 的位置停止。
::::

:::WorkflowBlockItem
**创建 PetController 脚本**

在 Project 窗口中点击 **+ 按钮 > ZEPETO > TypeScript** 创建一个新的脚本，并命名为 **PetController**。

打开脚本并粘贴下面的代码。

```typescript
import { Transform } from 'UnityEngine'
import { NavMeshAgent } from 'UnityEngine.AI';
import { ZepetoPlayers } from 'ZEPETO.Character.Controller'
import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
import { WorldService } from 'ZEPETO.World';

export default class PetController extends ZepetoScriptBehaviour {

    private _target: Transform;
    private _navMeshAgent: NavMeshAgent;

    Start() {
        this._navMeshAgent = this.GetComponent<NavMeshAgent>();

        ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
            this._target = ZepetoPlayers.instance.GetPlayer(WorldService.userId).character.transform;
        })
    }

    Update() {
        if (this._target == null) {
            return;
        }
        this._navMeshAgent.SetDestination(this._target.position);
    }
}
```

脚本说明

- 脚本开始时，将 \_target 设置为你的 ZEPETO 角色。
- 在 Update 函数中，每一帧会通过 SetDestination 将角色的位置设置为 NavMesh 的目标点。
:::

:::WorkflowBlockItem
**将 PetController 脚本应用到 Pet 对象上**

在 Hierarchy 中选择 Pet 对象，在 Inspector 中点击 **Add Component > Zepeto Script**，然后将刚才创建的 PetController 脚本拖入 Script 栏中。
:::

:::WorkflowBlockItem
**点击播放按钮**

![](https://api.archbee.com/api/optimize/xv-TGeWVTX2GDZMFGOf1Y/yq6fVGzeb3eN12XefOpQe_petexample.gif)

你现在可以看到 Pet 对象会跟随你的角色移动，并能够自然地避开墙壁等障碍物。
:::
:::::



# 创建角色头顶的 Pet

如果你希望 Pet 不是跟随角色，而是附着在角色身体上，可以使用对象附着的方式。

:::hint{type="info"}
✏️ 有关对象粘贴的详细内容请参考 [将物体附加到ZEPETO角色](docId\:R6xCzNe-z5w8UyCBGa18u) 指南。
:::



::::WorkflowBlock
:::WorkflowBlockItem
**创建 AttachPetController 脚本**

在 Project 中点击 **+ > ZEPETO > TypeScript**，创建新脚本并命名为 AttachPetController。

打开脚本并粘贴下方的代码。

```typescript
import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
import { ZepetoCharacter, ZepetoPlayers } from 'ZEPETO.Character.Controller';
import { Transform, Animator, GameObject, HumanBodyBones, Object } from 'UnityEngine';

export default class AttachPetController extends ZepetoScriptBehaviour {

    public Pet: GameObject;
    public bodyBone: HumanBodyBones;

    Start() {

        ZepetoPlayers.instance.OnAddedLocalPlayer.AddListener(() => {
            const localCharacter = ZepetoPlayers.instance.LocalPlayer.zepetoPlayer.character;            
            const animator: Animator = localCharacter.ZepetoAnimator;            
            const bone: Transform = animator.GetBoneTransform(this.bodyBone);            
            Object.Instantiate(this.Pet, bone) as GameObject;          
        });
    }
}
```

脚本说明

- 脚本启动后会查找本地玩家并获取其 Animator。
- 通过 bodyBone 变量识别所选身体部位并获取其位置。
- 随后在该位置 Instantiate 出 Pet 对象，并将其 parent 设为对应的身体部位。
:::

:::WorkflowBlockItem
**将 AttachPetController 脚本应用到新对象**

在 Hierarchy 中点击 **+ > Create Empty** 创建一个新对象，命名为 **AttachPetController**。

在 Inspector 中点击 **Add Component > Zepeto Script**，
将 AttachPetController 脚本拖入 Script 栏中。

将 Pet 对象拖入 Pet 字段，并在 bodyBone 下拉菜单中选择要附着的角色身体部位。

![](https://api.archbee.com/api/optimize/xv-TGeWVTX2GDZMFGOf1Y/nyLMD6vjoovCAoxHTe8OC_image.png)

点击播放按钮，即可看到 Pet 对象生成在你选择的身体部位上。
:::
::::

