はじめに
NavMeshAgentを使って敵キャラを動かそうとしたのに、まったく動かない…。
あるいは、途中までは動くのに急に止まる、目的地にたどり着かない。
こんな状況、一度は経験したことがあるかもしれません。
特に敵AIを作り始めたタイミングでよく起きるトラブルです。
ややこしいのは、「原因が1つではない」ことです。
NavMeshの設定、Agentのパラメータ、経路の計算、さらにはAnimatorなどの別コンポーネントまで影響してきます。
例えばこんなケースがあります。
- NavMeshは見えているのに動かない
- SetDestinationを呼んでいるのに進まない
- 途中まで行って急に止まる
- アニメーションだけ動いて本体が移動しない
一見バラバラに見えますが、実は「どのレイヤーで問題が起きているか」を切り分けると、一気に解決に近づきます。
私自身も最初は「何が悪いのか全然わからない…」と何時間も悩んだことがありますが、
原因の分類を理解してからは、数分で特定できるようになりました。
ここからは、まず最優先で確認すべきポイントを押さえて、そのあとに原因ごとに整理していきます。
まず最初に確認すべき5つ
動かない原因を細かく探る前に、まずはここだけ確認してみてください。
この5つのどれかに引っかかっているケースがかなり多いです。
- NavMesh上にいるか(isOnNavMeshがtrueか)
- speed / acceleration が0になっていないか
- SetDestinationが成功しているか(戻り値がtrueか)
- pathStatusがPathCompleteになっているか
- isStoppedがtrueになっていないか
それぞれのポイントを少しだけ補足しておきます。
NavMesh上にいるか
NavMeshAgentは、NavMeshの上にいないと一切移動できません。
見た目では乗っているように見えても、内部的にズレていることがあります。
speed / acceleration
値が0だと「動こうとしているのに進まない」状態になります。
意外と見落としがちなポイントです。
SetDestinationの戻り値
SetDestinationは常に成功するわけではありません。
falseが返っている場合、その時点で移動処理は始まっていません。
pathStatus
経路が「完全に到達可能(PathComplete)」でないと、途中で止まったり、動かないことがあります。
isStopped
このフラグがtrueだと、経路があっても停止したままになります。
スクリプトで知らないうちにtrueにしているケースもよくあります。

この5つを順番に確認するだけで、「何が原因か」がかなり絞れます。
ここで解決しなかった場合は、次のセクションで原因ごとに細かく見ていきます。
NavMesh系の問題
まず最初に疑うべきは「そもそも移動できる状態かどうか」です。
NavMeshに関する問題は、設定ミスというより“前提条件が満たされていない”ケースが多いです。
エージェントがNavMesh上にいない
まったく動かない場合、まずここを疑います。
NavMeshAgentは、NavMeshの上に存在していないと移動処理そのものが実行されません。
よくある症状
- SetDestinationを呼んでも反応しない
- エラーは出ていないのに動かない
- シーン上では乗っているように見える
原因
- スポーン位置がNavMesh外
- 地形とAgentの高さが微妙にズレている
- Bake後にオブジェクトを動かしている
解決方法
- 以下のコードで確認する
Debug.Log(agent.isOnNavMesh);
- falseならNavMesh外なので位置を修正
- Warpで強制的に乗せるのも有効
agent.Warp(validPosition);
注意点
見た目では正しく配置されていても、内部的にはNavMesh外というケースがあります。
特に坂や段差、スケール変更したオブジェクト周りで発生しやすいです。
再発防止のコツ
- スポーン位置はNavMesh上に限定する
- NavMesh.SamplePositionで補正する
判断基準
isOnNavMeshがfalseなら、その時点で移動しない原因は確定です。
NavMeshが正しくBakeされていない
次に多いのが「そもそも歩けるエリアが存在していない」ケースです。
よくある症状
- pathStatusがInvalidになる
- 目的地を設定しても動かない
- シーンに青いNavMeshが表示されない
原因
- Static設定がされていない
- Walkableとしてマークされていない
- NavMeshSurfaceの対象レイヤーに含まれていない
解決方法
- NavigationウィンドウでBakeし直す
- 対象オブジェクトに「Navigation Static」を設定
- NavMeshSurfaceのLayer設定を確認
注意点
Unityのバージョンによっては、NavMeshSurface(AI Navigationパッケージ)を使っているかどうかで設定方法が変わります。
プロジェクトごとに確認が必要です。
再発防止のコツ
- Bake後に必ずSceneビューで確認する
- 地形変更後は再Bakeする習慣をつける
判断基準
NavMesh(青い領域)が見えない場合、そのエリアは絶対に移動できません。
Agent設定の問題
NavMesh自体に問題がない場合、次に見るべきはNavMeshAgentの設定です。
ここは「動くはずなのに動かない」という、少しやっかいな状態になりやすいポイントです。
speed / acceleration が0になっている
意外と多いのがこのケースです。
移動処理自体は実行されているのに、速度が0なので結果として動いていないように見えます。
よくある症状
- SetDestinationは成功している
- エラーも出ていない
- でもキャラがピクリとも動かない
原因
- Inspectorでspeedが0になっている
- スクリプトで意図せず0を代入している
解決方法
- Inspectorでspeedを確認(例:3〜5程度)
- accelerationも0になっていないかチェック
判断基準
speedが0でなければ「最低限は動く条件」を満たしています。
isStoppedがtrueになっている
NavMeshAgentは、isStoppedがtrueだと完全に停止します。
経路があっても動かないため、原因に気づきにくいポイントです。
よくある症状
- 途中まで動いたのに急に止まる
- 再度SetDestinationしても動かない
原因
- 攻撃処理や状態遷移でisStoppedをtrueにしている
- 解除(falseに戻す)処理を書いていない
解決方法
- 以下のように明示的に解除する
agent.isStopped = false;
注意点
AI制御では「止める処理」はよく書くのに、「再開する処理」を忘れがちです。
状態遷移とセットで管理するとミスが減ります。
判断基準
isStoppedがtrueなら、他の条件が正しくても絶対に動きません。
stoppingDistanceが大きすぎる
目的地に到達する前に止まってしまう場合、この設定が原因のことがあります。
よくある症状
- 目的地の手前で止まる
- あと少しで到達しそうなのに動かない
原因
- stoppingDistanceが大きすぎる
解決方法
- 値を小さくする(例:0.1〜1程度)
注意点
攻撃AIなどでは「近づきすぎないため」にあえて大きく設定することもあります。
その場合は仕様なのかバグなのかを切り分けて考える必要があります。
判断基準
目的地との距離がstoppingDistance以下になると停止する、という仕様を覚えておくと判断しやすくなります。
経路計算の問題
NavMeshにもAgent設定にも問題がない場合、「経路(Path)」の状態を確認します。
ここは見落とされやすいですが、「動くかどうか」を決める重要な要素です。
pathPending中で止まっている
SetDestinationを呼んだ直後は、すぐに動き出さないことがあります。
これは経路を計算している途中だからです。
よくある症状
- 一瞬止まってから動き出す
- フレームによって挙動が不安定に見える
原因
- NavMeshAgentが経路を計算中(pathPending = true)
解決方法
- pathPendingがfalseになるまで待つ
- 状態を確認してから処理を行う
if (!agent.pathPending)
{
// 経路確定後の処理
}
注意点
経路計算はフレームをまたぐことがあります。
「SetDestinationしたのに動かない」と感じる場合、実はまだ計算中ということも多いです。
判断基準
pathPendingがtrueの間は「まだ動かなくても正常」です。
pathStatusがPartial / Invalidになっている
目的地にたどり着けない場合、NavMeshAgentは途中で止まるか、そもそも動きません。
よくある症状
- 途中まで進んで止まる
- まったく動かない
- ランダムに動作が変わる
原因
- 目的地がNavMesh外にある
- 障害物で完全に遮断されている
- NavMeshが途切れている
解決方法
- 目的地をNavMesh上に設定する
- NavMesh.SamplePositionで補正する
NavMeshHit hit;
if (NavMesh.SamplePosition(targetPosition, out hit, 1.0f, NavMesh.AllAreas))
{
agent.SetDestination(hit.position);
}
注意点
Partialは「途中までは行けるが、目的地には届かない状態」です。
見た目だけだと「バグっぽく」見えるので要注意です。
判断基準
- PathComplete → 正常
- PathPartial → 一部のみ到達可能
- PathInvalid → 無効(移動不可)

経路の状態は見えないため、デバッグしないと気づきにくいポイントです。
ライン表示などを使って可視化すると、一気に理解しやすくなります。
外部コンポーネントとの競合
ここまで問題が見つからない場合、「別のコンポーネントが移動を邪魔している」可能性が高いです。
特にAnimatorとNavMeshObstacleは、NavMeshAgentの挙動に強く影響します。
Animator(Root Motion)の影響
アニメーションによる移動(Root Motion)が有効になっていると、NavMeshAgentの移動が上書きされます。
よくある症状
- アニメーションは動いているのに位置が変わらない
- NavMeshAgentの速度を変えても動きが変わらない
- 動きがガタガタする
原因
- Animatorの「Apply Root Motion」がONになっている
解決方法
- Apply Root MotionをOFFにする
- またはNavMeshAgentではなくアニメーション側で移動を制御する
注意点
NavMeshAgentとRoot Motionは「どちらが移動を担当するか」を明確に分ける必要があります。
両方が同時に動こうとすると、ほぼ確実に不具合になります。
判断基準
Animatorを一時的にOFFにして動くなら、原因はほぼRoot Motionです。
私もここでかなり時間を溶かした経験があります…🙂
「NavMeshは全部正しいのに動かない」という時は、まずここを疑うと早いです。
NavMeshObstacleによる遮断
NavMeshObstacleは障害物として機能しますが、設定によってはNavMeshそのものを削ってしまいます。
よくある症状
- 突然その場で止まる
- 特定の場所に行けない
- 経路が途中で消える
原因
- ObstacleのCarvingがONになっている
- 移動中のオブジェクトがNavMeshを削っている
解決方法
- Carvingの設定を確認する
- Obstacleのサイズや配置を見直す
注意点
Carvingは「動的にNavMeshに穴を開ける」機能です。
便利ですが、意図しない場所で経路が切れる原因にもなります。
判断基準
特定の位置でだけ止まる場合、Obstacleの影響を疑うと切り分けやすいです。
すぐ確認できる診断チェックリスト
原因を一つずつ考えるのが大変なときは、チェックリスト形式で順番に確認していくのが一番早いです。
上から順に見ていくだけで、ほとんどのケースはどこかで引っかかります。
- □ isOnNavMeshがtrueになっているか
- □ NavMesh(青い領域)が正しくBakeされているか
- □ speed / acceleration が0になっていないか
- □ SetDestinationがtrueを返しているか
- □ pathStatusがPathCompleteか
- □ isStoppedがtrueになっていないか
- □ Animatorをオフにしても動かないか
- □ 特定の場所だけ止まっていないか(Obstacleの影響)
迷ったときは、次の順番で確認するとスムーズです。
- NavMeshに乗っているか(isOnNavMesh)
- NavMeshが存在するか(Bake状態)
- Agentの設定(speed / isStopped)
- 経路(pathStatus)
- 外部コンポーネント(Animator / Obstacle)
この順番には理由があります。
上にあるほど「そもそも動けない根本原因」で、下に行くほど「条件次第で発生する問題」になります。
例えば、isOnNavMeshがfalseの状態で他の設定をいくら調整しても絶対に動きません。
逆に、上の項目がすべてOKなら、かなり高い確率で原因は絞り込めています。

一度この流れでチェックできるようになると、デバッグのスピードが一気に上がります。
よくある誤解と注意点
NavMeshAgentが動かない原因を探していると、「実は仕様どおりだった」というケースもよくあります。
ここでは特につまずきやすい誤解を整理しておきます。
NavMeshがあれば動くと思っている
NavMeshが表示されているだけでは不十分です。
NavMeshAgent自身がその上に正しく配置されていないと、一切動きません。
補足:「NavMesh」と「NavMeshAgent」は別のものです。
床(NavMesh)があっても、キャラ(Agent)が床の外にいれば歩けない、というイメージです。
SetDestinationすれば必ず移動すると思っている
SetDestinationは「目的地を設定する」だけで、移動できるかどうかは別問題です。
よくある落とし穴
- 目的地がNavMesh外
- 経路が途中で途切れている
- pathStatusがPartial / Invalid
補足:「目的地設定」と「経路生成」は別ステップです。
この違いを理解すると、原因の切り分けがかなり楽になります。
止まるのはバグだと思っている
実は、止まるのは正常な挙動であることも多いです。
- stoppingDistanceに到達した
- isStoppedがtrueになっている
- 目的地に到達した
補足:「止まる理由」が仕様か異常かを見分けることが大切です。
ログや状態を確認して判断するクセをつけると、無駄な調査が減ります。
Animatorは移動に関係ないと思っている
AnimatorのRoot Motionは、NavMeshAgentの移動を完全に上書きします。
よくある状態
- アニメーションだけ進む
- 位置が変わらない
補足:移動の制御は「NavMeshかRoot Motionか」のどちらかに統一する必要があります。
一度動いたから設定は正しいと思っている
これもかなり多い誤解です。
例えば次のようなケースがあります。
- 特定の位置だけ動かない(Obstacle)
- 特定の条件で止まる(isStopped)
- 経路によって挙動が変わる(PathPartial)
補足:「常に再現するかどうか」を確認すると、問題の種類が見えてきます。
一度だけ動いたという情報は、逆にヒントになります。
「条件によって変わる問題」かどうかを意識して見ると、原因にたどり着きやすくなります。
NavMeshの仕組みを理解する
原因を切り分けやすくするために、NavMeshの構造をシンプルに整理しておきます。
ここを理解しておくと、「どこで問題が起きているか」が一気に見えるようになります。
NavMesh・Agent・Pathの3つでできている
NavMeshの移動は、次の3つの要素で成り立っています。
| 要素 | 役割 | イメージ |
|---|---|---|
| NavMesh | 移動できるエリア | 床・地面 |
| NavMeshAgent | 移動するキャラ | プレイヤーや敵 |
| Path | 目的地までのルート | ナビのルート |
この3つのどこかに問題があると、必ず動かなくなります。
どこが壊れているかで原因が変わる
トラブルの種類は、この3つのどこに問題があるかで分類できます。
- NavMeshが問題 → そもそも歩けない
- Agentが問題 → 動けるけど動かない
- Pathが問題 → 途中で止まる・到達できない
例えば、こんなイメージです。
- 床がない → どうやっても歩けない
- キャラが止まっている → 動く設定になっていない
- 道が途切れている → 途中までしか進めない
こうやって考えると、「何を確認すればいいか」が自然と見えてきます。
なぜ原因が分かりにくいのか
NavMeshのデバッグが難しい理由は、この3つが完全に分離されているからです。
- 見た目ではNavMeshとPathが分からない
- Agentの状態はコードを見ないと分からない
- 複数の要素が同時に影響する
そのため、なんとなく設定を触っても解決しにくいです。
逆に言うと、今回紹介したように
- NavMesh
- Agent
- Path
- 外部コンポーネント
この順番で切り分けていけば、かなりの確率で原因にたどり着けます。

ここまで理解できていると、「なぜ動かないのか」を論理的に説明できるようになります。
デバッグのスピードもぐっと上がりますよ。
AI実装を楽にする方法
ここまで見てきたように、NavMeshAgentの制御は「動かすだけ」なら簡単でも、実際のAIになると一気に複雑になります。
例えばこんな処理を作ろうとすると、一気に難易度が上がります。
- プレイヤーを見つけたら追いかける
- 近づいたら攻撃して止まる
- 見失ったら巡回に戻る
これを全部if文で書いていくと、すぐに「条件分岐地獄」になります…。
ビヘイビアツリーを使うと管理が楽になる
こういうときによく使われるのが「ビヘイビアツリー」です。
AIの行動をツリー構造で整理できるので、状態管理がかなり分かりやすくなります。
例えば次のように整理できます。
- 敵を見つけた → 追跡
- 距離が近い → 攻撃
- 見失った → 巡回
コードだけで書くよりも、「今どの状態にいるか」が視覚的に分かるのが大きなメリットです。
実務ではアセットを使うことも多い
実際の開発では、こういったAIロジックをすべて自作するよりも、専用ツールを使うことが多いです。
特に規模が大きくなると、状態管理・デバッグ・拡張性の面で差が出てきます。
このようなツールを使うと、
- 状態管理が視覚化できる
- 条件分岐の整理がしやすい
- デバッグが圧倒的に楽になる
といったメリットがあります。

NavMeshAgent単体で動かす段階を超えたら、「どう管理するか」も重要になってきます。
特に敵AIをしっかり作りたい場合は、一度検討してみる価値があります。
まとめ
NavMeshAgentが動かないときは、原因を一つずつ潰すよりも「どの層で問題が起きているか」を切り分けるのが一番早いです。
確認の優先順位をもう一度整理しておきます。
- NavMesh上にいるか(isOnNavMesh)
- NavMeshが正しく存在するか(Bake状態)
- Agentの設定(speed / isStopped)
- 経路の状態(pathStatus)
- 外部コンポーネント(Animator / Obstacle)
この順番で見ていけば、「どこが原因か」はかなり高い確率で特定できます。
実際にハマりやすいポイントを挙げると、
- NavMesh上に乗っていない
- Root Motionで移動が上書きされている
この2つが特に多い印象です。
「全部設定は正しいはずなのに動かない」と感じたときほど、基本に立ち返って確認するのが大切です。
一度この切り分けの考え方が身につくと、他の不具合にも応用できます。
デバッグのスピードもかなり変わってくるはずです。
よくある質問(FAQ)
- QNavMeshAgent.isOnNavMeshがfalseになる原因は?
- A
主に「NavMesh外に配置されている」ことが原因です。
- スポーン位置がNavMesh外
- 地形との高さがズレている
- Bake後に地形やオブジェクトを動かした
見た目では問題なさそうでも、内部的には外れていることがあります。
不安な場合はNavMesh.SamplePositionで補正するのが安全です。
- QPathPartialでも動いているなら問題ない?
- A
動いているように見えても、完全には目的地に到達できていません。
PathPartialは「途中までしか行けない経路」です。
例えば壁の手前までは行くけど、その先には進めない状態です。目的地まで確実に到達させたい場合は、PathCompleteになっているかを確認する必要があります。
- QRigidbodyとNavMeshAgentは一緒に使っていい?
- A
基本的にはあまりおすすめされません。
理由は、移動の制御が競合するからです。
- NavMeshAgent → 経路に沿って移動する
- Rigidbody → 物理演算で動く
両方が同時に位置を動かそうとすると、挙動が不安定になります。
どうしても併用する場合は、
- NavMeshAgentで移動しつつ、Rigidbodyは回転のみ使う
- 物理を使うときはNavMeshAgentを一時停止する
といったように、役割を分けることが重要です。








※当サイトはアフィリエイト広告を利用しています。リンクを経由して商品を購入された場合、当サイトに報酬が発生することがあります。
※本記事に記載しているAmazon商品情報(価格、在庫状況、割引、配送条件など)は、執筆時点のAmazon.co.jp上の情報に基づいています。
最新の価格・在庫・配送条件などの詳細は、Amazonの商品ページをご確認ください。