【Unity】NavMeshをランタイムで構築できるNavMeshComponents

UnityでNavMeshをランタイムで構築できるNavMeshComponentsを使う方法をまとめました。

Unity2019.2.6

インストール

NavMeshComponentsはUnityに含まれていないので、以下のgithubからインストールする必要があります。

github.com

ダウンロードした後、NavMeshComponentsフォルダを自身のプロジェクトのAssetsフォルダ配下にコピーすればOKです。

それでは早速Nav Meshをビルドしてみます。
まず以下のように適当にモデルを組み合わせたシーンを用意しておきます。

f:id:halya_11:20191020022041p:plain

ランタイムでナビメッシュを構築するため、これらのオブジェクトのNavigation Staticは外しておいても問題ないです。

f:id:halya_11:20191020022500p:plain

次にシーン上に空のGameObjectを作り、NavMeshSurfaceコンポーネントをアタッチします。

f:id:halya_11:20191020022112p:plain

この状態でBakeボタンを押下すると、NavMeshが構築されます。

f:id:halya_11:20191020022138p:plain

ランタイムでNav Meshをビルドするには、NavMeshSurface.BuildNavMesh()を呼びます。

using UnityEngine;
using UnityEngine.AI;

public class Example : MonoBehaviour
{
    [SerializeField]
    private NavMeshSurface _surface;

    public void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space)) {
            // NavMeshをビルドする
            _surface.BuildNavMesh();
        }
    }
}

ビルドする対象を絞り込む

さて前節の設定では、シーンに置かれているメッシュ全てからNav Meshをビルドしています。
対象のメッシュを絞り込むには、Nav Mesh Surfaceの以下の項目を設定します。

f:id:halya_11:20191020022716p:plain

各項目の説明は以下の通りです。

項目名 説明
Collect Objects 座標やHierarchyから絞り込む
- All : シーンの全てのGameObjectを対象にする
- Volume : 指定した直方体に収まる範囲だけビルドする
- Childeren : Nav Mesh Surfaceの子GameObjectだけ対象にする
Include Layers 選択したレイヤーに所属するGameObjectのみを対象にする
Use Geometry どのジオメトリを元にNavMeshをビルドするか
- Render Meshes : レンダリングに使うメッシュを元にビルド
- Physics Collider : コライダーの形状を元にビルド

メッシュごとにビルド設定する

前節ではビルド対象を絞り込みました。
次にこのビルド対象について、例えば「このGameObjectだけはビルド対象から除外したい」といった場合の設定方法を見ていきます。

このようなケースでは、対象のGameObjectにNav Mesh Modifierコンポーネントをアタッチします。

f:id:halya_11:20191020024208p:plain

Ignore From Buildにチェックを入れるとこのGameObjectはビルド時に除外されます。

また、Override Areaにチェックを入れるとNavigationのArea設定を上書きできます。

f:id:halya_11:20191020024325p:plain

最後のAffected Agentsは、このModfierを影響させるエージェントタイプを指定します。

領域ごとにビルド設定する

Area Typeの上書きはGameObjectではなく立方体の領域で指定することもできます。
このためにはNav Mesh Modifier Volumesコンポーネントを適当なGameObjectにアタッチします。

f:id:halya_11:20191020025131p:plain

例えば指定した領域のArea TypeをNot Walkableに変更すると以下のようになります。

f:id:halya_11:20191020025332p:plain

NavMeshLinkを使うと、繋がっていないNav Meshを繋ぐようなNavMeshを作成できます。
使用するにはまず適当なGameObjectにNav Mesh Linkコンポーネントをアタッチします。

f:id:halya_11:20191020031654p:plain

StartPointとEndPointに繋ぎたい座標を入力し、WidthにNav Meshの幅を指定します。
この状態でビルドすると、以下のように繋がっていないNav Meshを繋ぐことができます。

f:id:halya_11:20191020031821p:plain

障害物の設定などは組み込みのNavigationの機能を使う

さてここまででNavMeshComponentsの説明は一通り終わりました。
これらの機能はあくまで既存のNavigation機能の拡張という位置付けです。

そのため、障害物の設定などは既存のNavigationを機能を使うことで実現します。

f:id:halya_11:20191020031937p:plain

この辺りは以下の記事で説明しているので、必要に応じて参照してください。

light11.hatenadiary.com

関連

light11.hatenadiary.com

参考

docs.unity3d.com

github.com