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

## 1. 機能概要

### 1.1 機能名
3Dナビゲーション - NavigationAgent3D/NavigationRegion3Dによる経路探索

### 1.2 機能説明
3Dナビゲーションシステムは、3Dゲームにおけるキャラクターやオブジェクトの自動経路探索を実現する。NavigationRegion3Dで移動可能な領域（ナビゲーションメッシュ）を定義し、NavigationAgent3Dでエージェントの経路計算と移動制御を行う。2Dナビゲーションと同様にA*アルゴリズムベースの経路探索、RVOによる障害物回避を提供し、さらに高さ情報を考慮した3D空間での経路探索をサポートする。

### 1.3 関連画面
- 3Dエディタビューポート（ナビゲーションメッシュ表示）
- NavigationMesh生成ダイアログ
- デバッグオーバーレイ（経路表示）

## 2. 機能詳細

### 2.1 主要機能一覧

| 機能ID | 機能名 | 説明 |
|--------|--------|------|
| F37-01 | 3D経路探索 | 3D空間でのA*経路探索 |
| F37-02 | ナビゲーションメッシュ | NavigationMeshによる領域定義 |
| F37-03 | 3D障害物回避 | 3D空間でのRVO回避計算 |
| F37-04 | 高さ考慮 | 斜面・段差を考慮した経路 |
| F37-05 | ナビゲーションリンク3D | 3D空間での領域間接続 |
| F37-06 | エージェント高さ | エージェントの高さパラメータ |
| F37-07 | Y速度保持 | 2D回避時のY軸速度保持 |

### 2.2 クラス構造

```
Node3D
    ├── NavigationRegion3D   (ナビゲーション領域)
    ├── NavigationLink3D     (ナビゲーションリンク)
    └── NavigationObstacle3D (障害物)

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

RefCounted
    ├── NavigationPathQueryParameters3D (クエリパラメータ)
    └── NavigationPathQueryResult3D     (クエリ結果)

Resource
    └── NavigationMesh       (ナビゲーションメッシュリソース)
```

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

| プロパティ名 | 型 | デフォルト値 | 説明 |
|-------------|-----|-------------|------|
| target_position | Vector3 | (0,0,0) | 目標位置 |
| path_desired_distance | float | 1.0 | パス到達判定距離(m) |
| target_desired_distance | float | 1.0 | ターゲット到達判定距離(m) |
| path_height_offset | float | 0.0 | パス高さオフセット |
| path_max_distance | float | 5.0 | パス逸脱時の再計算閾値 |
| navigation_layers | int | 1 | ナビゲーションレイヤーマスク |
| avoidance_enabled | bool | false | 障害物回避有効化 |
| height | float | 1.0 | エージェント高さ(m) |
| radius | float | 0.5 | エージェント半径(m) |
| use_3d_avoidance | bool | false | 3D回避計算使用 |
| keep_y_velocity | bool | true | 2D回避時にY速度を保持 |
| max_speed | float | 10.0 | 最大速度(m/s) |
| neighbor_distance | float | 50.0 | 回避対象検出距離(m) |
| max_neighbors | int | 10 | 最大近隣エージェント数 |
| time_horizon_agents | float | 1.0 | エージェント回避予測時間 |
| time_horizon_obstacles | float | 0.0 | 障害物回避予測時間 |
| avoidance_layers | int | 1 | 回避レイヤー |
| avoidance_mask | int | 1 | 回避マスク |
| avoidance_priority | float | 1.0 | 回避優先度(0-1) |

### 2.4 主要メソッド（NavigationAgent3D）

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

### 2.5 シグナル（NavigationAgent3D）

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

### 2.6 NavigationMeshプロパティ

| プロパティ名 | 型 | 説明 |
|-------------|-----|------|
| cell_size | float | セルサイズ |
| cell_height | float | セル高さ |
| agent_height | float | エージェント高さ |
| agent_radius | float | エージェント半径 |
| agent_max_climb | float | 最大段差高さ |
| agent_max_slope | float | 最大斜面角度 |
| region_min_size | float | 最小領域サイズ |
| edge_max_length | float | 最大エッジ長さ |
| edge_max_error | float | 最大エッジ誤差 |
| filter_low_hanging_obstacles | bool | 低い障害物フィルタ |
| filter_ledge_spans | bool | 崖フィルタ |
| filter_walkable_low_height_spans | bool | 歩行可能低高さフィルタ |

## 3. 処理フロー

### 3.1 3D経路探索フロー

```
[NavigationAgent3D.set_target_position()]
      │
      ▼
[NavigationServer3D.query_path()]
      │
      ├─ [3D A*経路探索]
      │       │
      │       ├─ 開始位置の最近接ポリゴン検索
      │       │
      │       ├─ ゴール位置の最近接ポリゴン検索
      │       │
      │       └─ 3D空間でのA*実行
      │               ├─ 高さ情報を考慮したコスト計算
      │               └─ 斜面・段差の通過判定
      │
      └─ [パス後処理]
              │
              ├─ Corridorfunnel → 3D経路平滑化
              ├─ Edgecentered → エッジ中心経路
              └─ None → 処理なし
      │
      ▼
[path_height_offsetの適用]
      │
      ▼
[path_changed シグナル発行]
```

### 3.2 3D障害物回避フロー

```
[NavigationAgent3D.set_velocity(velocity)]
      │
      ▼
[use_3d_avoidance チェック]
      │
      ├─ true → [3D RVO計算]
      │              │
      │              └─ 全軸での回避速度計算
      │
      └─ false → [2D RVO計算（XZ平面）]
                     │
                     ├─ velocity.y = 0 （Y軸無視）
                     │
                     └─ keep_y_velocity?
                             │
                             ├─ true → stored_y_velocity保存・復元
                             │
                             └─ false → Y速度を0に
      │
      ▼
[NavigationServer3D.agent_set_velocity()]
      │
      ▼
[RVO計算完了]
      │
      ▼
[_avoidance_done(safe_velocity)]
      │
      └─ [velocity_computed シグナル]
```

### 3.3 データフロー図

```
[NavigationRegion3D]      [NavigationMesh Resource]
        │                         │
        │                         │ bake()
        ▼                         ▼
┌───────────────────────────────────────────┐
│           NavigationServer3D               │
│                                            │
│  ┌──────────────────┐  ┌────────────────┐ │
│  │ 3D Navigation Map│  │ 3D RVO         │ │
│  │ - navmesh        │  │ Simulation     │ │
│  │ - links          │  │ - agents       │ │
│  │ - obstacles      │  │ - obstacles    │ │
│  │ - height data    │  │ - 3D/2D mode   │ │
│  └──────────────────┘  └────────────────┘ │
│           │                    │          │
│           ▼                    ▼          │
│  ┌──────────────────────────────────────┐ │
│  │    3D Path Query System              │ │
│  │  - A* with height                    │ │
│  │  - Slope/step handling               │ │
│  │  - 3D path smoothing                 │ │
│  └──────────────────────────────────────┘ │
└───────────────────────────────────────────┘
        │
        ▼
┌───────────────────┐
│ NavigationAgent3D │
│ - 3D path         │
│ - next_position   │
│ - height handling │
└───────────────────┘
```

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

### 4.1 推奨読解順序

1. **データ構造の理解**
   - `scene/3d/navigation/navigation_agent_3d.h`: NavigationAgent3D定義
   - `scene/3d/navigation/navigation_region_3d.h`: NavigationRegion3D定義

2. **エントリーポイント**
   - `navigation_agent_3d.cpp` **_bind_methods()** (36-207行目): GDScriptバインディング
   - `navigation_agent_3d.cpp` **_notification()** (245-344行目): ライフサイクル処理

3. **3D固有処理**
   - `navigation_agent_3d.cpp` (313-336行目): Y速度保持処理
   - `navigation_agent_3d.cpp` **_validate_property()** (346-351行目): プロパティ検証

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

#### 2D回避時のY速度保持（navigation_agent_3d.cpp: 317-327行目）
```cpp
if (velocity_submitted) {
    velocity_submitted = false;
    if (avoidance_enabled) {
        if (!use_3d_avoidance) {
            if (keep_y_velocity) {
                stored_y_velocity = velocity.y;  // Y速度を保存
            }
            velocity.y = 0.0;  // 2D計算のためY=0
        }
        NavigationServer3D::get_singleton()->agent_set_velocity(agent, velocity);
    }
}
```

#### heightプロパティ（3D固有）
```cpp
// 3Dエージェントは高さパラメータを持つ
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0.01,100,0.01"), ...);
```

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

```
NavigationAgent3D::set_target_position(position)
    │
    └── [NavigationServer3D::query_path()が呼ばれる]
            │
            ├── 3D A*経路探索
            │       ├─ 高さを考慮したコスト計算
            │       └─ 斜面角度チェック（agent_max_slope）
            │
            └── path_postprocessing
                    └─ 3D funnel algorithm

NavigationAgent3D::_notification(NOTIFICATION_INTERNAL_PHYSICS_PROCESS)
    │
    ├── agent_set_position(global_position)
    │
    └── [velocity処理]
            │
            ├── use_3d_avoidance?
            │       │
            │       ├── true → 3D RVO
            │       │
            │       └── false → 2D RVO + Y velocity handling
            │                       │
            │                       └── keep_y_velocity → stored_y_velocity
            │
            └── agent_set_velocity()
                    │
                    └── _avoidance_done(safe_velocity)
                            │
                            └── emit_signal("velocity_computed")
```

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

| ファイルパス | 種別 | 役割 |
|-------------|------|------|
| scene/3d/navigation/navigation_agent_3d.h | ヘッダー | NavigationAgent3D定義 |
| scene/3d/navigation/navigation_agent_3d.cpp | 実装 | エージェント実装 |
| scene/3d/navigation/navigation_region_3d.h | ヘッダー | NavigationRegion3D定義 |
| scene/3d/navigation/navigation_link_3d.h | ヘッダー | NavigationLink3D定義 |
| scene/3d/navigation/navigation_obstacle_3d.h | ヘッダー | NavigationObstacle3D定義 |
| servers/navigation_3d/navigation_server_3d.h | ヘッダー | サーバー定義 |
| scene/resources/3d/navigation_mesh.h | ヘッダー | NavigationMeshリソース |

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

### 5.1 2Dナビゲーションとの違い
- 高さパラメータ（height）の追加
- 3D/2D回避モードの選択（use_3d_avoidance）
- Y速度保持オプション（keep_y_velocity）
- NavigationMeshによる複雑な地形対応

### 5.2 パフォーマンス
- NavigationMeshの事前ベイク
- cell_size/cell_heightによる解像度調整
- path_search_max_polygonsによる探索制限

### 5.3 地形対応
- agent_max_climbで段差制限
- agent_max_slopeで斜面制限
- filter系オプションで不要領域除外

## 6. 使用例

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

func _ready():
    agent.velocity_computed.connect(_on_velocity_computed)

func set_movement_target(target: Vector3):
    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:
        $CharacterBody3D.velocity = velocity
        $CharacterBody3D.move_and_slide()

func _on_velocity_computed(safe_velocity: Vector3):
    $CharacterBody3D.velocity = safe_velocity
    $CharacterBody3D.move_and_slide()
```

### 6.2 3D回避の設定
```gdscript
func _ready():
    agent.avoidance_enabled = true
    agent.use_3d_avoidance = true  # 完全3D回避
    # または
    agent.use_3d_avoidance = false
    agent.keep_y_velocity = true   # 2D回避でY速度保持
```

### 6.3 NavigationMeshのベイク設定
```gdscript
func bake_navigation():
    var navmesh = NavigationMesh.new()
    navmesh.agent_height = 2.0
    navmesh.agent_radius = 0.5
    navmesh.agent_max_climb = 0.5
    navmesh.agent_max_slope = 45.0
    navmesh.cell_size = 0.25
    navmesh.cell_height = 0.25

    $NavigationRegion3D.navigation_mesh = navmesh
    $NavigationRegion3D.bake_navigation_mesh()
```

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