🚶

NavMeshLinkを使ったAgentの転移を実装

2024/09/01に公開

前書き

本記事では、NavMeshが使える環境であることを前提として進めていきます。
また、Unityのバージョンによって仕様が異なる可能性があります。

本記事の成果物

https://youtu.be/qbzpc3aksxE

本文

まず、初めに今回NavMeshLinkを使う理由について説明します。
NavMeshLinkを使用せずにAgentを目的地まで移動させる場合、間に障害物が存在していると迂回して目的地を目指そうとします。下記はその様子です。
https://youtu.be/grUmhCjuE3c
この時、Agentの真横に目的地に直通する転移装置があったと仮定します。それでもAgentは転移装置を目指さずに上記の動画のように壁を迂回して目的地を目指します。これは、Agentが転移装置を使用した場合に目的地に辿り着けることを認識していない為です。
そこでNavMeshLinkを使い、転移装置から目的地まで移動できるということをAgentに認識させることがNavMeshLinkを使う理由となります。

  • NavMeshLink の UnityUserManual
     - NavMeshLinkは、新たに使用可能な通路をAgentに認識させられるComponent。
     - 始点から終点までの直線をTransformで移動させる。
     - 間に障害物があっても使用可能な通路として認識する

転移に使用するNavMeshLinkを配置する

初めにNavMeshLinkのComponentをアタッチしたオブジェクトを用意します。

コピペ用: NavMeshLink
実際に設置すると下記のような見た目になると思われます。
なお、可視化する為にはシーンビューでGizmosを有効にしている必要があります。

次に、NavMeshLinkのインスペクタービューについて上から順番に説明していきます。

Agent Type

このNavMeshLinkを使用するAgentの種類。

Start/End Point

NavMeshLinkの始点と終点の位置をローカル座標系で変更できます。

Swap

始点と終点を入れ替えます。

Align Transform

このボタンをクリックすると、リンクの中心点でゲームオブジェクトを移動し、Transform の前方への軸をリンクの終点に揃えます。

引用元:NavMeshLink の UnityUserManual

Width

値を大きくすると始点と終点の判定が横に大きくなるイメージです。

Cost Modifier

経路探索時に使用するコストです。A*アルゴリズムのように、そのタイルを通過する場合に使用するコストを設定できます。NavMeshLinkでは負の値があらかじめ入力されており、事前にベイクされた通路より優先して選ばれるように設計されているようです。

Auto Update Position

trueの場合、Transformが動的(ランタイム中)に変更された時、始点や終点のワールド座標が更新されるかどうかを取得/設定します。

Bidirectional

falseにすると一方通行になります(始点から終点へ)。

Area Type

NavMesh Link に適用するエリアタイプ (これは経路探索に影響を与えます)

引用元:NavMeshLink の UnityUserManual

C#
if (_agent.isOnOffMeshLink) // Update内での使用を想定した条件文
{
    // 現在のOffMeshLinkDataを取得
    var currentLink = _agent.currentOffMeshLinkData;

    // Linkの終点を取得
    Vector3 endPos = currentLink.endPos;

    // Agentの大きさから半分の高さを求める
    Vector3 halfHeight = transform.localScale.y * Vector3.up;

    // 終点へ移動
    _agent.transform.position = endPos + halfHeight;

    // 移動を終了
    _agent.CompleteOffMeshLink();
}

可能な限りシンプルな実装にしました。

転移後のAgentの挙動に着目すると分かるのですが、前回の位置から移動先を引き継いでいる所為で転移後も転移前と同じ方向に移動してしまっています。
実際のプロジェクトで使用する際は、転移の前後に待機時間を設けて移動方向の再計算をさせるとより自然なAgentの転移を実装できるのではないでしょうか。
https://youtu.be/qbzpc3aksxE

使用例

https://youtu.be/q6jM4HjXZCs

Discussion