# 機能設計書 17-レイキャスト

## 概要

本ドキュメントは、Godotエンジンにおけるレイキャスト機能の設計仕様を記述する。レイキャスト機能は、RayCast2D/RayCast3Dノードを使用して、特定の方向に仮想的な光線を投射し、その光線が衝突するオブジェクトを検出する機能である。視線判定、照準、障害物検出などに使用される。

### 本機能の処理概要

**業務上の目的・背景**：ゲーム開発において、プレイヤーの視線方向や銃の照準方向に何があるかを検出することは、多くのゲームロジックで必要となる。レイキャストは、物理シミュレーションよりも軽量で、特定方向への即座の衝突検出を提供する。

**機能の利用シーン**：
- FPSゲームでの銃の照準と射撃判定
- 視線判定（敵がプレイヤーを見ているか）
- 地面検出（キャラクターが地面に立っているか）
- 障害物検出（車両のセンサー）
- インタラクション可能なオブジェクトの検出

**主要な処理内容**：
1. レイの開始点と終点の計算
2. PhysicsDirectSpaceStateを通じた衝突検出
3. 衝突点、法線、衝突オブジェクトの取得
4. 除外リストによる特定オブジェクトの除外
5. コリジョンマスクによるレイヤーフィルタリング

**関連システム・外部連携**：
- PhysicsServer2D/3D：衝突検出の実行
- PhysicsDirectSpaceState2D/3D：直接空間クエリ
- CollisionObject2D/3D：衝突対象

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | 2Dエディタ | 主画面 | 2Dレイキャストのプレビュー・設定 |
| 4 | 3Dエディタ | 主画面 | 3Dレイキャストのプレビュー・設定 |

## 機能種別

物理クエリ / ゲームプレイロジック

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| enabled | bool | No | レイキャスト有効化 | - |
| target_position | Vector2/Vector3 | No | ターゲット位置（ローカル座標） | - |
| collision_mask | uint32_t | No | コリジョンマスク（1-32） | 1-32の範囲 |
| exclude_parent | bool | No | 親ボディを除外 | - |
| collide_with_areas | bool | No | エリアとの衝突を検出 | - |
| collide_with_bodies | bool | No | ボディとの衝突を検出 | - |
| hit_from_inside | bool | No | 内側からのヒットを検出 | - |
| hit_back_faces | bool | No | 裏面へのヒットを検出（3Dのみ） | - |

### 入力データソース

- エディタでのプロパティ設定
- スクリプトからの動的設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| collided | bool | 衝突したかどうか |
| collision_point | Vector2/Vector3 | 衝突点（グローバル座標） |
| collision_normal | Vector2/Vector3 | 衝突面の法線 |
| collider | Object | 衝突したオブジェクト |
| collider_rid | RID | 衝突したオブジェクトのRID |
| collider_shape | int | 衝突したシェイプのインデックス |
| collision_face_index | int | 衝突した面のインデックス（3Dのみ） |

### 出力先

- スクリプトからのAPI呼び出し結果
- デバッグ描画

## 処理フロー

### 処理シーケンス

```
1. NOTIFICATION_INTERNAL_PHYSICS_PROCESSで更新
   └─ enabledがtrueの場合のみ
2. World2D/3Dから空間状態を取得
   └─ space_get_direct_state()
3. RayParametersを構築
   └─ from, to, exclude, collision_mask等
4. intersect_rayを実行
   └─ PhysicsDirectSpaceState::intersect_ray()
5. 結果を保存
   └─ collided, collision_point, collision_normal等
6. 前回と状態が変わった場合は再描画
   └─ queue_redraw()
```

### フローチャート

```mermaid
flowchart TD
    A[NOTIFICATION_INTERNAL_PHYSICS_PROCESS] --> B{enabled?}
    B -->|No| C[スキップ]
    B -->|Yes| D[_update_raycast_state]
    D --> E[World2D/3Dを取得]
    E --> F[space_get_direct_state]
    F --> G[RayParameters構築]
    G --> H[intersect_ray実行]
    H --> I{衝突あり?}
    I -->|Yes| J[衝突情報を保存]
    I -->|No| K[状態をクリア]
    J --> L{前回と状態変化?}
    K --> L
    L -->|Yes| M[queue_redraw]
    L -->|No| N[終了]
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 親除外 | exclude_parentがtrueの場合、親CollisionObjectを除外 | 親がCollisionObjectの場合 |
| BR-02 | レイヤーマスク | collision_maskで指定されたレイヤーのみ検出 | 常時 |
| BR-03 | ゼロベクトル対策 | target_positionがゼロの場合、微小値(0.01)を使用 | target_position==Vector2/3() |

### 計算ロジック

レイ終点計算:
```cpp
ray_params.from = gt.get_origin();
ray_params.to = gt.xform(target_position);
```

## データベース操作仕様

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | エラー | World2D/3Dがnull | シーンツリーへの追加を確認 |
| - | エラー | PhysicsDirectSpaceStateがnull | 物理サーバーの初期化を確認 |

### リトライ仕様

なし

## トランザクション仕様

なし

## パフォーマンス要件

- レイキャストは物理フレームごとに実行
- force_raycast_update()で即時更新可能
- 複数レイキャストは並列処理可能

## セキュリティ考慮事項

特になし

## 備考

- RayCast2Dのデフォルトtarget_position: Vector2(0, 50)（下方向50px）
- RayCast3Dのデフォルトtarget_position: Vector3(0, -1, 0)（下方向1m）

---

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

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

RayCast2Dの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ray_cast_2d.h | `scene/2d/physics/ray_cast_2d.h` | RayCast2Dクラスのメンバ変数 |

**読解のコツ**: collided、collision_point、collision_normal、againstなどの結果格納変数と、target_position、collision_mask、excludeなどの設定変数を区別する。

#### Step 2: エントリーポイントを理解する

ノードのライフサイクルを追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ray_cast_2d.cpp | `scene/2d/physics/ray_cast_2d.cpp` | _notification関数 |

**主要処理フロー**:
1. **140-156行目**: NOTIFICATION_ENTER_TREE - 物理処理有効化、親除外設定
2. **158-162行目**: NOTIFICATION_EXIT_TREE - 物理処理無効化
3. **164-170行目**: NOTIFICATION_DRAW - デバッグ描画
4. **172-177行目**: NOTIFICATION_INTERNAL_PHYSICS_PROCESS - レイキャスト更新

#### Step 3: レイキャスト実行を理解する

_update_raycast_state関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ray_cast_2d.cpp | `scene/2d/physics/ray_cast_2d.cpp` | _update_raycast_state関数 |

**主要処理フロー**:
- **181-186行目**: World2DとPhysicsDirectSpaceStateの取得
- **188-193行目**: ゼロベクトル対策
- **195-206行目**: RayParametersの構築
- **207-219行目**: intersect_rayの実行と結果の保存

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

```
RayCast2D::_notification(NOTIFICATION_INTERNAL_PHYSICS_PROCESS)
    │
    └─ RayCast2D::_update_raycast_state()
           │
           ├─ get_world_2d()
           │
           ├─ PhysicsServer2D::space_get_direct_state()
           │
           └─ PhysicsDirectSpaceState2D::intersect_ray()
                  │
                  └─ RayResult構造体に結果を格納
```

### データフロー図

```
[入力]                    [処理]                         [出力]

target_position ──────▶ _update_raycast_state()
collision_mask               │
exclude                      ▼
                       RayParameters作成
                              │
                              ▼
                       intersect_ray()
                              │
                              ▼
                       RayResult ──────────▶ collision_point
                                              collision_normal
                                              collider
                                              collider_rid
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ray_cast_2d.cpp | `scene/2d/physics/ray_cast_2d.cpp` | ソース | 2Dレイキャスト実装 |
| ray_cast_2d.h | `scene/2d/physics/ray_cast_2d.h` | ヘッダ | 2Dレイキャスト定義 |
| ray_cast_3d.cpp | `scene/3d/physics/ray_cast_3d.cpp` | ソース | 3Dレイキャスト実装 |
| ray_cast_3d.h | `scene/3d/physics/ray_cast_3d.h` | ヘッダ | 3Dレイキャスト定義 |
| shape_cast_2d.cpp | `scene/2d/physics/shape_cast_2d.cpp` | ソース | 2Dシェイプキャスト |
| shape_cast_3d.cpp | `scene/3d/physics/shape_cast_3d.cpp` | ソース | 3Dシェイプキャスト |
