# 機能設計書: 2Dナビゲーション

## 1. 機能概要

### 1.1 機能名
2Dナビゲーション - NavigationAgent2D/NavigationRegion2Dによる経路探索

### 1.2 機能説明
2Dナビゲーションシステムは、2Dゲームにおけるキャラクターやオブジェクトの自動経路探索を実現する。NavigationRegion2Dで移動可能な領域（ナビゲーションメッシュ）を定義し、NavigationAgent2Dでエージェントの経路計算と移動制御を行う。A*アルゴリズムベースの経路探索、障害物回避（RVO：Reciprocal Velocity Obstacles）、ナビゲーションリンクによる領域間接続などの機能を提供する。

### 1.3 関連画面
- 2Dエディタビューポート（ナビゲーションメッシュ表示）
- NavigationRegion2Dポリゴンエディタ
- デバッグオーバーレイ（経路表示）

## 2. 機能詳細

### 2.1 主要機能一覧

| 機能ID | 機能名 | 説明 |
|--------|--------|------|
| F36-01 | 経路探索 | A*アルゴリズムによる最短経路計算 |
| F36-02 | ナビゲーション領域定義 | 移動可能領域のポリゴン定義 |
| F36-03 | 障害物回避 | RVOによる動的障害物回避 |
| F36-04 | ナビゲーションリンク | 領域間のジャンプ・テレポート接続 |
| F36-05 | レイヤーマスク | ナビゲーション領域のフィルタリング |
| F36-06 | パス後処理 | 経路の最適化・簡略化 |
| F36-07 | 障害物定義 | 静的/動的障害物の設定 |

### 2.2 クラス構造

```
Node2D
    ├── NavigationRegion2D   (ナビゲーション領域)
    ├── NavigationLink2D     (ナビゲーションリンク)
    └── NavigationObstacle2D (障害物)

Node
    └── NavigationAgent2D    (エージェント)

RefCounted
    ├── NavigationPathQueryParameters2D (クエリパラメータ)
    └── NavigationPathQueryResult2D     (クエリ結果)
```

### 2.3 主要プロパティ（NavigationAgent2D）

| プロパティ名 | 型 | デフォルト値 | 説明 |
|-------------|-----|-------------|------|
| target_position | Vector2 | (0,0) | 目標位置 |
| path_desired_distance | float | 20.0 | パス到達判定距離(px) |
| target_desired_distance | float | 10.0 | ターゲット到達判定距離(px) |
| path_max_distance | float | 100.0 | パス逸脱時の再計算閾値 |
| navigation_layers | int | 1 | ナビゲーションレイヤーマスク |
| pathfinding_algorithm | int | AStar | 経路探索アルゴリズム |
| path_postprocessing | int | Corridorfunnel | パス後処理方式 |
| avoidance_enabled | bool | false | 障害物回避有効化 |
| radius | float | 10.0 | エージェント半径 |
| neighbor_distance | float | 500.0 | 回避対象検出距離 |
| max_neighbors | int | 10 | 最大近隣エージェント数 |
| time_horizon_agents | float | 1.0 | エージェント回避予測時間 |
| time_horizon_obstacles | float | 0.0 | 障害物回避予測時間 |
| max_speed | float | 100.0 | 最大速度(px/s) |
| avoidance_layers | int | 1 | 回避レイヤー |
| avoidance_mask | int | 1 | 回避マスク |
| avoidance_priority | float | 1.0 | 回避優先度(0-1) |
| debug_enabled | bool | false | デバッグ表示有効化 |

### 2.4 主要プロパティ（NavigationRegion2D）

| プロパティ名 | 型 | デフォルト値 | 説明 |
|-------------|-----|-------------|------|
| navigation_polygon | NavigationPolygon | null | ナビゲーションポリゴン |
| enabled | bool | true | 有効フラグ |
| navigation_layers | int | 1 | ナビゲーションレイヤー |
| enter_cost | float | 0.0 | 領域進入コスト |
| travel_cost | float | 1.0 | 領域移動コスト |

### 2.5 主要メソッド（NavigationAgent2D）

| メソッド名 | 戻り値 | 説明 |
|-----------|--------|------|
| get_rid() | RID | エージェントのRIDを取得 |
| set_target_position(position) | void | 目標位置を設定 |
| get_next_path_position() | Vector2 | 次の経路点を取得 |
| is_target_reached() | bool | 目標到達判定 |
| is_target_reachable() | bool | 目標到達可能判定 |
| is_navigation_finished() | bool | ナビゲーション完了判定 |
| get_final_position() | Vector2 | 最終到達位置を取得 |
| distance_to_target() | float | 目標までの距離 |
| get_current_navigation_path() | PackedVector2Array | 現在の経路を取得 |
| get_current_navigation_path_index() | int | 現在の経路インデックス |
| get_current_navigation_result() | NavigationPathQueryResult2D | 経路結果オブジェクト |
| set_velocity(velocity) | void | 回避計算用速度を設定 |
| set_velocity_forced(velocity) | void | 強制的に速度を設定 |
| get_path_length() | float | 経路の総距離 |

### 2.6 シグナル（NavigationAgent2D）

| シグナル名 | 引数 | 説明 |
|-----------|------|------|
| path_changed | なし | 経路が変更された時 |
| target_reached | なし | 目標に到達した時 |
| waypoint_reached | details: Dictionary | ウェイポイント通過時 |
| link_reached | details: Dictionary | リンク通過時 |
| navigation_finished | なし | ナビゲーション完了時 |
| velocity_computed | safe_velocity: Vector2 | 回避計算完了時 |

## 3. 処理フロー

### 3.1 経路探索フロー

```
[NavigationAgent2D.set_target_position()]
      │
      ▼
[NavigationServer2D.query_path()]
      │
      ├─ [A*経路探索]
      │       │
      │       ├─ 開始ポリゴン検索
      │       │
      │       ├─ ゴールポリゴン検索
      │       │
      │       └─ A*アルゴリズム実行
      │               ├─ オープンリスト管理
      │               ├─ コスト計算（g + h）
      │               └─ 最短経路構築
      │
      └─ [パス後処理]
              │
              ├─ Corridorfunnel → 経路平滑化
              ├─ Edgecentered → エッジ中心経路
              └─ None → 処理なし
      │
      ▼
[path_changed シグナル発行]
      │
      ▼
[navigation_result更新]
```

### 3.2 エージェント移動フロー

```
[_physics_process(delta) - 毎フレーム]
      │
      ▼
[get_next_path_position()]
      │
      ├─ 経路が空？ → 終了
      │
      └─ 現在位置と比較
              │
              ├─ path_desired_distance以内？
              │       └─ 次のウェイポイントへ
              │               └─ [waypoint_reached シグナル]
              │
              └─ 目標までtarget_desired_distance以内？
                      └─ [target_reached シグナル]
                              └─ [navigation_finished シグナル]
      │
      ▼
[velocity計算]
      │
      ├─ avoidance_enabled?
      │       │
      │       ├─ Yes → [set_velocity()]
      │       │            │
      │       │            ▼
      │       │       [NavigationServer2D.agent_set_velocity()]
      │       │            │
      │       │            ▼
      │       │       [RVO計算]
      │       │            │
      │       │            └─ [velocity_computed シグナル]
      │       │                     └─ safe_velocity適用
      │       │
      │       └─ No → 直接velocity適用
      │
      ▼
[move_and_slide() または position更新]
```

### 3.3 データフロー図

```
[NavigationRegion2D]      [NavigationObstacle2D]
        │                         │
        │ NavigationPolygon       │ 障害物形状
        ▼                         ▼
┌───────────────────────────────────────────┐
│           NavigationServer2D               │
│                                            │
│  ┌──────────────────┐  ┌────────────────┐ │
│  │ Navigation Map   │  │ RVO Simulation │ │
│  │ - polygons       │  │ - agents       │ │
│  │ - links          │  │ - obstacles    │ │
│  │ - obstacles      │  │ - velocities   │ │
│  └──────────────────┘  └────────────────┘ │
│           │                    │          │
│           ▼                    ▼          │
│  ┌──────────────────────────────────────┐ │
│  │        Path Query System             │ │
│  │  - A* pathfinding                    │ │
│  │  - Path postprocessing               │ │
│  │  - Avoidance calculation             │ │
│  └──────────────────────────────────────┘ │
└───────────────────────────────────────────┘
        │                         │
        ▼                         ▼
┌───────────────────┐    ┌───────────────────┐
│ NavigationAgent2D │    │  velocity_computed │
│ - current_path    │    │  シグナル          │
│ - next_position   │    └───────────────────┘
└───────────────────┘
```

## 4. コードリーディングガイド

### 4.1 推奨読解順序

1. **データ構造の理解**
   - `scene/2d/navigation/navigation_agent_2d.h`: NavigationAgent2D定義
   - `scene/2d/navigation/navigation_region_2d.h`: NavigationRegion2D定義

2. **エントリーポイント**
   - `navigation_agent_2d.cpp` **_bind_methods()** (38-196行目): GDScriptバインディング
   - `navigation_agent_2d.cpp` **_notification()** (226-319行目): ライフサイクル処理

3. **コア処理**
   - `navigation_agent_2d.cpp` **set_target_position()**: 経路探索開始
   - `navigation_agent_2d.cpp` **get_next_path_position()**: 次の経路点取得
   - `servers/navigation_2d/navigation_server_2d.cpp`: サーバー側処理

### 4.2 重要な処理ポイント

#### _bind_methods()での主要プロパティ登録（navigation_agent_2d.cpp: 143-169行目）
```cpp
ADD_GROUP("Pathfinding", "");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "target_position"), "set_target_position", "get_target_position");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_desired_distance"), "set_path_desired_distance", ...);
// ...

ADD_GROUP("Avoidance", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "avoidance_enabled"), "set_avoidance_enabled", ...);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius"), "set_radius", "get_radius");
// ...
```

#### NavigationAgent2Dコンストラクタ（navigation_agent_2d.cpp: 321-348行目）
```cpp
NavigationAgent2D::NavigationAgent2D() {
    agent = NavigationServer2D::get_singleton()->agent_create();

    NavigationServer2D::get_singleton()->agent_set_neighbor_distance(agent, neighbor_distance);
    NavigationServer2D::get_singleton()->agent_set_max_neighbors(agent, max_neighbors);
    // ... 初期設定
}
```

### 4.3 プログラム呼び出し階層図

```
NavigationAgent2D::set_target_position(position)
    │
    └── target_position_submitted = true
            │
            └── [次の_physics_process()で]
                    │
                    └── _request_repath()  [経路再計算]
                            │
                            └── NavigationServer2D::query_path()
                                    │
                                    ├── _pathfinding_algorithm()
                                    │       └── A*アルゴリズム
                                    │
                                    └── _path_postprocessing()
                                            ├── CORRIDOR_FUNNEL
                                            ├── EDGE_CENTERED
                                            └── NONE

NavigationAgent2D::get_next_path_position()
    │
    ├── [経路存在チェック]
    │
    └── [current_path_index更新]
            │
            ├── emit_signal("waypoint_reached", details)
            │
            └── [目標到達チェック]
                    │
                    ├── emit_signal("target_reached")
                    │
                    └── emit_signal("navigation_finished")

NavigationAgent2D::set_velocity(velocity)  [avoidance有効時]
    │
    └── NavigationServer2D::agent_set_velocity(agent, velocity)
            │
            └── [RVO計算]
                    │
                    └── _avoidance_done(safe_velocity)
                            │
                            └── emit_signal("velocity_computed", safe_velocity)
```

### 4.4 関連ファイル一覧

| ファイルパス | 種別 | 役割 |
|-------------|------|------|
| scene/2d/navigation/navigation_agent_2d.h | ヘッダー | NavigationAgent2D定義 |
| scene/2d/navigation/navigation_agent_2d.cpp | 実装 | エージェント実装 |
| scene/2d/navigation/navigation_region_2d.h | ヘッダー | NavigationRegion2D定義 |
| scene/2d/navigation/navigation_region_2d.cpp | 実装 | 領域実装 |
| scene/2d/navigation/navigation_link_2d.h | ヘッダー | NavigationLink2D定義 |
| scene/2d/navigation/navigation_obstacle_2d.h | ヘッダー | NavigationObstacle2D定義 |
| servers/navigation_2d/navigation_server_2d.h | ヘッダー | サーバー定義 |
| scene/resources/2d/navigation_polygon.h | ヘッダー | ナビゲーションポリゴンリソース |

## 5. 設計上の考慮事項

### 5.1 パフォーマンス
- NavigationServer2Dによるマルチスレッド対応
- 経路のキャッシュと遅延再計算
- path_search_max_polygonsによる探索範囲制限

### 5.2 精度と品質
- path_postprocessingによる経路品質向上
- simplify_pathによる不要なウェイポイント削除
- avoidance_priorityによる回避優先度制御

### 5.3 拡張性
- ナビゲーションレイヤーによる領域分離
- NavigationLink2Dによる領域間接続
- カスタムコスト（enter_cost, travel_cost）

## 6. 使用例

### 6.1 基本的な経路追従
```gdscript
@onready var agent = $NavigationAgent2D

func _ready():
    # シグナル接続
    agent.velocity_computed.connect(_on_velocity_computed)

func set_movement_target(target: Vector2):
    agent.target_position = target

func _physics_process(delta):
    if agent.is_navigation_finished():
        return

    var next_position = agent.get_next_path_position()
    var direction = (next_position - global_position).normalized()
    var velocity = direction * agent.max_speed

    if agent.avoidance_enabled:
        agent.set_velocity(velocity)
    else:
        velocity = move_and_slide()

func _on_velocity_computed(safe_velocity: Vector2):
    velocity = move_and_slide()
```

### 6.2 ナビゲーションレイヤーの使用
```gdscript
func _ready():
    # 特定のレイヤーのみ使用
    agent.navigation_layers = 0b00000011  # レイヤー1と2

    # 特定レイヤーの設定
    agent.set_navigation_layer_value(1, true)
    agent.set_navigation_layer_value(3, false)
```

### 6.3 障害物回避の設定
```gdscript
func _ready():
    agent.avoidance_enabled = true
    agent.radius = 32.0
    agent.max_speed = 200.0
    agent.neighbor_distance = 500.0
    agent.max_neighbors = 10
    agent.time_horizon_agents = 1.0
```

### 6.4 ウェイポイント到達の検出
```gdscript
func _ready():
    agent.waypoint_reached.connect(_on_waypoint_reached)
    agent.link_reached.connect(_on_link_reached)
    agent.navigation_finished.connect(_on_navigation_finished)

func _on_waypoint_reached(details: Dictionary):
    print("Waypoint reached: ", details)

func _on_link_reached(details: Dictionary):
    # ジャンプ・テレポート処理
    print("Link reached: ", details)

func _on_navigation_finished():
    print("Arrived at destination!")
```

## 7. 関連機能
- [No.37 3Dナビゲーション](./37-3Dナビゲーション.md) - 3D版の経路探索
