---
title: キャラクターを追従するオブジェクトの実装
slug: world-sdk-guide-ja/IN4937yC3rczau2SwNCb9
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に含めたいオブジェクトを選択して追加してください。

- これにより、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のプロパティを調整すると、Petのサイズ、移動速度、回転速度、加速度、障害物と認識する高さなどを設定できます。

:::hint{type="info"}
✏️ NavMeshAgentの詳細については、以下の[リンク](https://docs.unity3d.com/550/Documentation/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関数では毎フレーム、NavMeshAgentのSetDestination関数を使ってキャラクターの位置を目的地に設定します。
:::

:::WorkflowBlockItem
**PetControllerスクリプトをPetオブジェクトに適用します。**

HierarchyでPetオブジェクトを選択し、Inspectorで**Add Component > Zepeto Script**をクリックします。

Scriptフィールドに作成したPetControllerスクリプトをドラッグ＆ドロップしてください。
:::

:::WorkflowBlockItem
**再生ボタンを押します。**

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

Petオブジェクトがキャラクターについてきて、壁などの障害物を避けながら移動する様子が確認できます。
:::
:::::



# キャラクターの頭上にPetを乗せる

Petをキャラクターに追従させるのではなく、キャラクターの体に固定したい場合は、オブジェクトのアタッチ機能を使ってみてください。

:::hint{type="info"}
✏️ オブジェクトの添付の詳細については、[ZEPETOキャラクターにオブジェクトを取り付ける](docId:3BS1KBLCtl2WpPpAH2-Ws) ガイドを参照してください
:::



::::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で選択した体の部位をAnimatorから取得し、その位置にPetオブジェクトを生成（Instantiate）します。
- このとき、Petオブジェクトのparentには取得した体の部位が指定されます。
:::

:::WorkflowBlockItem
**AttachPetControllerスクリプトを新しいオブジェクトに適用します。**

Hierarchyで **+ ボタン > Create Empty** をクリックして新しいオブジェクトを作成し、**AttachPetController**という名前をつけます。

Inspectorで **Add Component > Zepeto Script** をクリックし、ScriptフィールドにAttachPetControllerスクリプトをドラッグ＆ドロップします。

Petフィールドに使用するPetオブジェクトをドラッグし、bodyBoneフィールドのドロップダウンから取り付けたい体の部位を選択します。

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

再生ボタンを押すと、Petオブジェクトが指定した体の部位に生成されていることが確認できます。
:::
::::

