NavMeshってそもそも何?

スポンサーリンク

Unityでゲームを作っていると、「敵がプレイヤーを追いかけてくる」という動作を実装したくなる場面が出てきます。でも、単純に「プレイヤーの方向に移動させる」だけでは、壁や障害物にぶつかって止まってしまいます😅

そこで登場するのが NavMesh(Navigation Mesh、ナビゲーションメッシュ) です。

NavMesh とは、ゲームのステージ上で「キャラクターが歩ける場所」を事前に計算してメッシュ(面)として保存する仕組みです。この情報をもとに、Unity は障害物を避けながら目的地までの最短ルートを自動的に探索してくれます。

人間でいえば、GoogleマップがナビゲーションするときにGPS情報と地図データを使うのと同じイメージです。NavMesh が「地図」で、NavMeshAgent が「ナビ付きの乗り物」といった感じですね。

NavMeshの仕組みをざっくり理解する

NavMesh は大きく次の2つの要素で構成されています。

要素 役割
NavMesh(地図データ) ステージ上の通行可能エリアを事前に計算してベイク(焼き付け)したもの
NavMeshAgent(移動するキャラクター) NavMeshの情報を使って自動で経路を探索しながら移動するコンポーネント

ベイクとは、ステージの形状を解析して「どこを歩けるか」を計算してファイルに保存することです。ゲーム実行時には、この保存済みデータをもとにリアルタイムで経路計算が行われます。

下の図は NavMesh の俯瞰イメージです。青いエリアが「通行可能」、灰色のブロックが「障害物」、赤い線が NavMesh が計算した経路です。

NavMeshの俯瞰イメージ
NavMeshの俯瞰イメージ。青エリアが歩行可能範囲、赤線が経路探索結果

図を見ると、赤線(経路)が障害物を避けながらプレイヤーまで繋がっているのがわかります。これを毎フレーム再計算することで、プレイヤーが動いても追従できるようになります。

NavMeshをベイクする手順

まず最初に行うのが NavMesh のベイクです。手順はシンプルです。

① 障害物に「Static」を設定する

ステージの壁・床・障害物として使うオブジェクトを選択し、Inspectorウィンドウの右上にある Static チェックボックスをオンにします(Navigation Static を含む)。これで「このオブジェクトはNavMeshの計算に使う」とUnityに伝えることができます。

② NavigationウィンドウでBakeする

Unity のメニューから Window → AI → Navigation を開き、Bake タブを選択します。

NavMeshのBake設定画面
NavigationウィンドウのBakeタブ。主要パラメータを設定してBakeボタンを押す

主要な設定項目は以下の通りです。

パラメータ 意味 目安値
Agent Radius キャラクターの横幅の半径。小さいほど狭い隙間も通れる 0.5
Agent Height キャラクターの身長。低い天井をくぐれるかどうかに影響 2.0
Max Slope 歩ける坂の最大角度(度) 45°
Step Height 乗り越えられる段差の高さ 0.4

設定できたら Bake ボタンを押します。少し待つと、Scene ビューのステージ上に青いメッシュが表示されます。これが NavMesh の通行可能エリアです。

⚠️ ハマりポイント:最初は Bake を押しても何も表示されず焦りました。原因は Static フラグをオブジェクトに設定し忘れていたこと。Static にしていないオブジェクトは NavMesh の計算対象外になるので注意です。

NavMeshAgentで敵を動かすC#スクリプト

NavMesh をベイクしたら、次は敵キャラクターに NavMeshAgent コンポーネントを追加します。

敵オブジェクトを選択して Inspector → Add Component → Navigation → Nav Mesh Agent を追加してください。

あとは C# スクリプトで毎フレーム「プレイヤーの座標を目的地にセット」するだけです。

EnemyChase.csのコード
EnemyChase.cs ── NavMeshAgentを使ってプレイヤーを追跡するスクリプト

コードのポイントは agent.SetDestination(player.position) の1行だけです。これを Update() の中で毎フレーム呼ぶことで、プレイヤーが動いてもリアルタイムに追従します。

using UnityEngine;
using UnityEngine.AI;

public class EnemyChase : MonoBehaviour
{
    NavMeshAgent agent;
    Transform player;

    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
        player = GameObject.FindWithTag("Player").transform;
        agent.speed = 3.5f;           // 移動速度
        agent.stoppingDistance = 1.5f; // プレイヤーとの停止距離
    }

    void Update()
    {
        if (player != null)
        {
            agent.SetDestination(player.position);
        }
    }
}

このスクリプトを使う前に、プレイヤーオブジェクトのタグを "Player" に設定しておく必要があります。タグの設定は Inspector 上部の Tag ドロップダウンから行えます。

NavMeshAgentの主要パラメータ解説

NavMeshAgent コンポーネントにはさまざまなパラメータがあり、これを調整することで敵の動き方を細かく制御できます。

NavMeshAgentのInspector設定
NavMeshAgentコンポーネントの主要パラメータ
パラメータ 役割 調整のヒント
Speed 移動速度(m/s) プレイヤーより少し遅めにすると逃げ切れる緊張感が出る
Angular Speed 方向転換の速さ(度/s) 小さくすると旋回が鈍くなりリアル感が出る
Acceleration 加速度 大きいほどすぐに最高速に達する
Stopping Distance 目的地の手前で止まる距離 攻撃射程に合わせて設定する
Radius エージェントの当たり判定半径 NavMesh のAgent Radiusと揃えると誤動作しにくい
Priority 複数エージェントが衝突したときの優先度 0が最高優先。複数の敵を出すときに重要

最初は Speed と Stopping Distance だけ触れば十分です。慣れてきたら Angular Speed を下げてみると、敵の動きがよりゲームらしくなります。

実装していてハマったポイント

実際に実装していていくつかハマりました。同じところで詰まる方の参考になれば😊

① 敵がその場でくるくる回り続ける

原因は NavMeshAgent の Radius とベイク時の Agent Radius が大きくずれていたためでした。たとえばベイク時の Radius が 0.5 なのに NavMeshAgent の Radius が 2.0 だと、エージェントが NavMesh に乗れない場所を目的地にしてしまい混乱します。両方の値を揃えると解消しました。

② 敵が急に別の場所にワープする

SetDestination() を呼ぶとき、プレイヤーが NavMesh の外(空中や地面の外)にいると経路が計算できずに異常な挙動をすることがあります。プレイヤー自体も NavMesh 上に乗っている状態にすることで解決しました。

③ 複数の敵が重なってしまう

NavMeshAgent 同士は自動で衝突回避しますが、Priority の値が同じだと競合することがあります。複数の敵を出す場合は Priority に少しずつ差をつけるか、Obstacle Avoidance の Quality を High Quality に設定すると改善されました。

④ 階段を登れない

NavMesh は「フラットな面」を基準に計算されるため、細かい段差のある階段はそのままでは歩けないことがあります。階段の上に細長い NavMesh Link(オフメッシュリンク)を設定するか、階段全体を1つの傾斜面で代用する方法が有効でした。

まとめ

UnityのNavMeshを使うと、複雑な地形でも障害物を自動で避けながら動く敵キャラクターをわずかなコードで実装できます。今回のポイントをまとめると次の通りです。

  • NavMesh は「歩けるエリアを事前計算したデータ」。Bake することで生成される
  • 障害物オブジェクトに Static フラグを設定しないとNavMeshに反映されない
  • NavMeshAgent に SetDestination() を呼ぶだけで自動経路探索が動く
  • Speed・Stopping Distance・Radius の3つを調整するだけでかなり動きが変わる
  • 複数の敵を出すときは Priority の設定が重要

NavMesh を使いこなすと「巡回する敵」「逃げたら追いかける敵」「グループで動く敵」など、さまざまな敵AIの基盤を同じ仕組みで作れるようになります。まずは今回の追跡敵から始めてみてはいかがでしょうか😊

それでは、今回はここまで。ありがとうございました😊