# 機能設計書 14-2D物理シミュレーション

## 概要

本ドキュメントは、Godotエンジンにおける2D物理シミュレーション機能の設計仕様を記述する。2D物理シミュレーションは、RigidBody2D、StaticBody2D、CharacterBody2D、Area2Dなどの物理ボディを使用して、重力、衝突、反発などの物理挙動をシミュレートする機能である。

### 本機能の処理概要

**業務上の目的・背景**：2Dゲーム開発において、リアルな物理挙動（落下、衝突、反発、摩擦）をシミュレートすることは、ゲームプレイの面白さと没入感を高める。本機能は、開発者が複雑な物理計算を意識せずに、直感的に物理挙動を設定できる仕組みを提供する。

**機能の利用シーン**：
- プラットフォーマーゲームのキャラクター移動と衝突
- パズルゲームでの物体の落下と積み重ね
- ピンボールやブロック崩しなどの物理ベースゲーム
- 物理ベースのUI演出（パーティクル、布シミュレーション風）
- トリガーエリアの検出（Area2D）

**主要な処理内容**：
1. PhysicsServer2Dによる物理ワールド管理
2. 物理ボディの位置・速度・力の計算
3. 衝突検出と応答処理
4. 重力と外力の適用
5. move_and_collideによるキネマティック移動
6. test_moveによる衝突テスト

**関連システム・外部連携**：
- PhysicsServer2D：物理エンジンのサーバーサイド実装
- CollisionObject2D：衝突オブジェクトの基底クラス
- CollisionShape2D/CollisionPolygon2D：衝突形状定義

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | 2Dエディタ | 主画面 | 2D物理ノードのプレビュー・デバッグ表示 |

## 機能種別

物理シミュレーション / ゲームプレイロジック

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| motion | Vector2 | Yes | 移動ベクトル | - |
| test_only | bool | No | テストのみ実行（位置更新しない） | - |
| safe_margin | float | No | 衝突マージン（デフォルト: 0.08） | 0以上 |
| recovery_as_collision | bool | No | 回復をコリジョンとして扱う | - |

### 入力データソース

- スクリプトからの直接呼び出し（move_and_collide、apply_force等）
- PhysicsServer2Dによる自動シミュレーション

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| collision | KinematicCollision2D | 衝突情報（衝突点、法線、衝突対象） |
| travel | Vector2 | 実際の移動量 |
| remainder | Vector2 | 残りの移動量 |
| collided | bool | 衝突したかどうか |

### 出力先

- 物理ボディの位置・回転
- シグナル発行（body_entered、body_exited等）

## 処理フロー

### 処理シーケンス

```
1. PhysicsServer2Dが物理ステップを開始
   └─ _physics_process呼び出し
2. 各物理ボディの状態を更新
   └─ 速度、位置、回転の計算
3. 衝突検出
   └─ ブロードフェーズ→ナローフェーズ
4. 衝突応答
   └─ 反発、摩擦、penetration解決
5. シグナル発行
   └─ body_entered、body_exited等
```

### フローチャート

```mermaid
flowchart TD
    A[move_and_collide呼び出し] --> B[MotionParameters作成]
    B --> C[PhysicsServer2D::body_test_motion]
    C --> D{衝突あり?}
    D -->|Yes| E[スライディング処理]
    D -->|No| F[全移動量を適用]
    E --> G[衝突情報を構築]
    F --> H[位置を更新]
    G --> H
    H --> I{test_only?}
    I -->|Yes| J[位置更新をスキップ]
    I -->|No| K[set_global_transform]
    J --> L[KinematicCollision2Dを返す]
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 同期移動禁止 | sync to physicsオプション有効時はmove関数使用不可 | is_only_update_transform_changes_enabled()がtrue |
| BR-02 | スライディング抑制 | cancel_slidingでスライディングを抑制可能 | 衝突深度が浅い場合 |
| BR-03 | 衝突例外 | add_collision_exception_withで特定ボディとの衝突を無視 | 明示的に設定した場合 |

### 計算ロジック

スライディング処理:
```
projected_length = travel.dot(motion_normal)
recovery = travel - motion_normal * projected_length
if recovery_length < margin + precision:
    travel = motion_normal * projected_length
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 警告 | sync to physicsとmove関数の同時使用 | どちらかを無効にする |
| - | 警告 | 物理補間未有効時 | physics_interpolation_modeを確認 |

### リトライ仕様

なし

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

なし

## パフォーマンス要件

- 物理シミュレーションは固定フレームレート（デフォルト60Hz）で実行
- 衝突検出はブロードフェーズ（空間分割）で高速化

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

特になし

## 備考

- PhysicsBody2Dはmove_and_collideとtest_moveを提供
- CharacterBody2Dはmove_and_slide（より高レベルAPI）を提供
- 物理ボディモード: STATIC, KINEMATIC, RIGID, RIGID_LINEAR

---

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

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

### 推奨読解順序

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

物理ボディの階層構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | collision_object_2d.h | `scene/2d/physics/collision_object_2d.h` | 衝突オブジェクト基底クラス |
| 1-2 | physics_body_2d.h | `scene/2d/physics/physics_body_2d.h` | PhysicsBody2Dの定義 |
| 1-3 | kinematic_collision_2d.h | `scene/2d/physics/kinematic_collision_2d.h` | 衝突情報の構造 |

**読解のコツ**: CollisionObject2D→PhysicsBody2D→RigidBody2D/StaticBody2D/CharacterBody2Dの継承関係を理解する。

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

move_and_collide関数の実装を追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | physics_body_2d.cpp | `scene/2d/physics/physics_body_2d.cpp` | PhysicsBody2Dの実装 |

**主要処理フロー**:
1. **49-67行目**: _move関数（move_and_collideのラッパー）
2. **69-121行目**: move_and_collide本体実装
3. **74行目**: PhysicsServer2D::body_test_motion呼び出し
4. **114-117行目**: 位置更新処理

#### Step 3: 各種ボディタイプを理解する

RigidBody2D、StaticBody2D、CharacterBody2Dの違いを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | rigid_body_2d.cpp | `scene/2d/physics/rigid_body_2d.cpp` | 動的物理ボディ |
| 3-2 | static_body_2d.cpp | `scene/2d/physics/static_body_2d.cpp` | 静的物理ボディ |
| 3-3 | character_body_2d.cpp | `scene/2d/physics/character_body_2d.cpp` | キャラクター制御用ボディ |

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

```
PhysicsBody2D::move_and_collide()
    │
    ├─ PhysicsServer2D::MotionParameters作成
    │
    ├─ PhysicsServer2D::body_test_motion()
    │      │
    │      └─ 内部で衝突検出実行
    │
    ├─ cancel_sliding処理（オプション）
    │
    └─ set_global_transform()
           │
           └─ 位置更新をPhysicsServer2Dに通知
```

### データフロー図

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

move_and_collide()
       │
       ▼
MotionParameters ──────▶ PhysicsServer2D
  - from                      │
  - motion                    ▼
  - margin            body_test_motion()
                              │
                              ▼
                       MotionResult ──────▶ KinematicCollision2D
                         - travel              - collision_point
                         - remainder           - collision_normal
                         - collision_*         - collider
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| physics_body_2d.cpp | `scene/2d/physics/physics_body_2d.cpp` | ソース | PhysicsBody2D基底クラス |
| rigid_body_2d.cpp | `scene/2d/physics/rigid_body_2d.cpp` | ソース | 動的物理ボディ |
| static_body_2d.cpp | `scene/2d/physics/static_body_2d.cpp` | ソース | 静的物理ボディ |
| character_body_2d.cpp | `scene/2d/physics/character_body_2d.cpp` | ソース | キャラクター用ボディ |
| area_2d.cpp | `scene/2d/physics/area_2d.cpp` | ソース | トリガーエリア |
| collision_object_2d.cpp | `scene/2d/physics/collision_object_2d.cpp` | ソース | 衝突オブジェクト基底 |
| kinematic_collision_2d.cpp | `scene/2d/physics/kinematic_collision_2d.cpp` | ソース | 衝突情報クラス |
