# 機能設計書 16-衝突検出

## 概要

本ドキュメントは、Godotエンジンにおける衝突検出機能の設計仕様を記述する。衝突検出機能は、CollisionShape2D/3DとCollisionPolygon2D/3Dを使用して、物理ボディやエリアの衝突判定形状を定義し、オブジェクト間の接触や重なりを検出する機能である。

### 本機能の処理概要

**業務上の目的・背景**：ゲーム開発において、オブジェクト同士の衝突を検出することは、ゲームロジックの基盤となる。キャラクターと壁の衝突、弾丸と敵の接触、アイテムの取得判定など、あらゆるインタラクションに衝突検出が必要である。

**機能の利用シーン**：
- キャラクターと環境（壁、床、障害物）の衝突
- 武器や弾丸と敵の接触判定
- アイテムやパワーアップの取得判定
- トリガーエリアへの進入検出
- 一方向コリジョン（プラットフォーマーの床）

**主要な処理内容**：
1. CollisionShapeの形状定義と管理
2. 親CollisionObjectへのシェイプ登録
3. 無効化/有効化の制御
4. 一方向コリジョンの設定
5. デバッグ表示の描画

**関連システム・外部連携**：
- CollisionObject2D/3D：親となる衝突オブジェクト
- Shape2D/Shape3D：衝突形状リソース
- PhysicsServer2D/3D：衝突判定の実行

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | 2Dエディタ | 主画面 | 2Dコリジョン形状の編集・プレビュー |
| 4 | 3Dエディタ | 主画面 | 3Dコリジョン形状の編集・プレビュー |

## 機能種別

衝突形状管理 / デバッグ表示

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| shape | Ref<Shape2D/3D> | No | 衝突形状リソース | 有効なShapeリソース |
| disabled | bool | No | 無効化フラグ | - |
| one_way_collision | bool | No | 一方向コリジョン有効化 | 2Dのみ |
| one_way_collision_margin | float | No | 一方向コリジョンのマージン | 0以上 |
| debug_color | Color | No | デバッグ表示色 | - |

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| owner_id | uint32_t | 親CollisionObjectでのオーナーID |
| shape_owner | CollisionObject2D/3D | シェイプを所有する親オブジェクト |

### 出力先

- PhysicsServer（衝突形状の登録）
- デバッグ描画（エディタ・ランタイム）

## 処理フロー

### 処理シーケンス

```
1. NOTIFICATION_PARENTEDで親オブジェクトを検出
   └─ CollisionObject2D/3Dにキャスト
2. シェイプオーナーを作成
   └─ collision_object->create_shape_owner(this)
3. シェイプを追加
   └─ shape_owner_add_shape(owner_id, shape)
4. シェイプオーナーの設定を更新
   └─ transform、disabled、one_way_collision
5. NOTIFICATION_UNPARENTEDでシェイプオーナーを削除
   └─ remove_shape_owner(owner_id)
```

### フローチャート

```mermaid
flowchart TD
    A[NOTIFICATION_PARENTED] --> B{親がCollisionObject?}
    B -->|Yes| C[create_shape_owner]
    B -->|No| D[スキップ]
    C --> E{shapeが有効?}
    E -->|Yes| F[shape_owner_add_shape]
    E -->|No| G[シェイプなしで続行]
    F --> H[_update_in_shape_owner]
    G --> H
    H --> I[終了]

    J[set_shape呼び出し] --> K{既存shapeあり?}
    K -->|Yes| L[changeシグナル切断]
    K -->|No| M[新shapeを設定]
    L --> M
    M --> N{collision_objectあり?}
    N -->|Yes| O[shape_owner_clear_shapes]
    O --> P[shape_owner_add_shape]
    P --> Q[changeシグナル接続]
    N -->|No| Q
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 親制約 | CollisionShape2D/3DはCollisionObject2D/3Dの子である必要がある | 常時 |
| BR-02 | 一方向制約 | 一方向コリジョンはArea2Dでは無効 | Area2Dが親の場合 |
| BR-03 | ポリゴン警告 | ConvexPolygon/ConcavePolygonはCollisionPolygon2Dを推奨 | 使用時 |

### 計算ロジック

デバッグ表示色の処理:
```cpp
if (disabled) {
    float g = draw_col.get_v();
    draw_col.r = g;
    draw_col.g = g;
    draw_col.b = g;
    draw_col.a *= 0.5;
}
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 警告 | 親がCollisionObject派生でない | 適切な親ノードに配置 |
| - | 警告 | シェイプが未設定 | Shape2D/3Dリソースを設定 |
| - | 警告 | Area2Dで一方向コリジョン使用 | 一方向コリジョンを無効化 |

### リトライ仕様

なし

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

なし

## パフォーマンス要件

- シェイプの変更はリアルタイムで反映
- デバッグ表示はエディタまたはデバッグモード時のみ

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

特になし

## 備考

- Shape2Dの種類: RectangleShape2D, CircleShape2D, CapsuleShape2D, ConvexPolygonShape2D, ConcavePolygonShape2D, SegmentShape2D, WorldBoundaryShape2D
- Shape3Dの種類: BoxShape3D, SphereShape3D, CapsuleShape3D, CylinderShape3D, ConvexPolygonShape3D, ConcavePolygonShape3D, WorldBoundaryShape3D, HeightMapShape3D

---

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

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

### 推奨読解順序

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

CollisionShape2Dの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | collision_shape_2d.h | `scene/2d/physics/collision_shape_2d.h` | CollisionShape2Dクラスのメンバ変数 |
| 1-2 | shape_2d.h | `scene/resources/2d/shape_2d.h` | Shape2D基底クラス |

**読解のコツ**: CollisionShape2Dはshape（Shape2Dリソース）を持ち、親のCollisionObject2Dに登録する。owner_idで親内での識別を行う。

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

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

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

**主要処理フロー**:
1. **52-63行目**: NOTIFICATION_PARENTED - シェイプオーナー作成
2. **65-69行目**: NOTIFICATION_ENTER_TREE - 設定更新
3. **71-75行目**: NOTIFICATION_LOCAL_TRANSFORM_CHANGED - トランスフォーム更新
4. **77-83行目**: NOTIFICATION_UNPARENTED - シェイプオーナー削除
5. **85-130行目**: NOTIFICATION_DRAW - デバッグ描画

#### Step 3: シェイプ設定を理解する

set_shape関数の実装を確認する。

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

**主要処理フロー**:
- **135-140行目**: 既存シェイプのchangeシグナル切断
- **142-150行目**: 新シェイプの設定とオーナーへの追加
- **152-154行目**: 新シェイプのchangeシグナル接続

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

```
CollisionShape2D::_notification(NOTIFICATION_PARENTED)
    │
    ├─ Object::cast_to<CollisionObject2D>(get_parent())
    │
    ├─ CollisionObject2D::create_shape_owner()
    │
    └─ CollisionObject2D::shape_owner_add_shape()
           │
           └─ PhysicsServer2D::area_add_shape() / body_add_shape()

CollisionShape2D::set_shape()
    │
    ├─ Shape2D::disconnect_changed()
    │
    ├─ CollisionObject2D::shape_owner_clear_shapes()
    │
    ├─ CollisionObject2D::shape_owner_add_shape()
    │
    └─ Shape2D::connect_changed()
```

### データフロー図

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

Shape2Dリソース ──────▶ CollisionShape2D
       │                      │
       ▼                      ▼
  形状データ           _update_in_shape_owner()
                              │
                              ▼
                       CollisionObject2D
                              │
                              ▼
                       PhysicsServer2D ──────▶ 衝突判定エンジン
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| collision_shape_2d.cpp | `scene/2d/physics/collision_shape_2d.cpp` | ソース | 2Dコリジョンシェイプ |
| collision_shape_3d.cpp | `scene/3d/physics/collision_shape_3d.cpp` | ソース | 3Dコリジョンシェイプ |
| collision_polygon_2d.cpp | `scene/2d/physics/collision_polygon_2d.cpp` | ソース | 2Dポリゴンコリジョン |
| collision_polygon_3d.cpp | `scene/3d/physics/collision_polygon_3d.cpp` | ソース | 3Dポリゴンコリジョン |
| shape_2d.cpp | `scene/resources/2d/shape_2d.cpp` | ソース | 2Dシェイプ基底 |
| shape_3d.cpp | `scene/resources/3d/shape_3d.cpp` | ソース | 3Dシェイプ基底 |
