# 機能設計書: Tween

## 1. 機能概要

### 1.1 機能名
Tween - プログラムによる補間アニメーション

### 1.2 機能説明
Tweenは、プログラムコードから直接プロパティ値を補間するアニメーションシステムである。開始値から終了値への滑らかな遷移を様々なイージング関数で実現する。UIアニメーション、カメラ移動、フェードエフェクトなど、スクリプトから動的に生成されるアニメーションに最適である。メソッドチェーンによる直感的なAPI設計が特徴。

### 1.3 関連画面
- なし（スクリプトベースの機能）

## 2. 機能詳細

### 2.1 主要機能一覧

| 機能ID | 機能名 | 説明 |
|--------|--------|------|
| F33-01 | プロパティ補間 | オブジェクトのプロパティを補間 |
| F33-02 | メソッド呼び出し補間 | メソッドを補間値で呼び出し |
| F33-03 | コールバック実行 | 指定タイミングでコールバック実行 |
| F33-04 | シーケンス制御 | 直列・並列のアニメーション構成 |
| F33-05 | イージング | 様々なイージング関数のサポート |
| F33-06 | ループ制御 | 繰り返し再生とヨーヨー再生 |
| F33-07 | 遅延実行 | アニメーション開始の遅延 |

### 2.2 クラス構造

```
RefCounted
    └── Tween
            │
            └── Tweener (補間ステップ基底)
                    ├── PropertyTweener
                    ├── IntervalTweener
                    ├── CallbackTweener
                    └── MethodTweener
```

### 2.3 主要プロパティ

| プロパティ名 | 型 | デフォルト値 | 説明 |
|-------------|-----|-------------|------|
| parallel | bool | false | 並列実行モード |
| loops | int | 1 | ループ回数（0で無限） |
| speed_scale | float | 1.0 | 再生速度スケール |
| pause_mode | TweenPauseMode | TWEEN_PAUSE_BOUND | 一時停止時の挙動 |
| process_mode | TweenProcessCallback | TWEEN_PROCESS_IDLE | 処理タイミング |

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

| メソッド名 | 戻り値 | 説明 |
|-----------|--------|------|
| tween_property(object, property, final_val, duration) | PropertyTweener | プロパティ補間を追加 |
| tween_interval(time) | IntervalTweener | 待機時間を追加 |
| tween_callback(callback) | CallbackTweener | コールバックを追加 |
| tween_method(method, from, to, duration) | MethodTweener | メソッド補間を追加 |
| custom_step(delta) | bool | 手動でステップ実行 |
| stop() | void | Tweenを停止 |
| pause() | void | Tweenを一時停止 |
| play() | void | Tweenを再開 |
| kill() | void | Tweenを破棄 |
| is_running() | bool | 実行中かどうか |
| is_valid() | bool | 有効かどうか |
| bind_node(node) | Tween | ノードにバインド |
| set_parallel(parallel) | Tween | 並列モード設定 |
| set_loops(loops) | Tween | ループ回数設定 |
| set_speed_scale(speed) | Tween | 速度スケール設定 |
| set_trans(trans) | Tween | トランジション設定 |
| set_ease(ease) | Tween | イージング設定 |
| parallel() | Tween | 次のTweenerを並列に |
| chain() | Tween | 次のTweenerを直列に |

### 2.5 PropertyTweenerのメソッド

| メソッド名 | 戻り値 | 説明 |
|-----------|--------|------|
| from(value) | PropertyTweener | 開始値を設定 |
| from_current() | PropertyTweener | 現在値を開始値に |
| as_relative() | PropertyTweener | 相対値として扱う |
| set_delay(delay) | PropertyTweener | 遅延を設定 |
| set_trans(trans) | PropertyTweener | トランジション設定 |
| set_ease(ease) | PropertyTweener | イージング設定 |
| set_custom_interpolator(interpolator) | PropertyTweener | カスタム補間関数 |

### 2.6 イージング関数

#### TransitionType
| 定数 | 説明 |
|------|------|
| TRANS_LINEAR | 線形 |
| TRANS_SINE | サイン波 |
| TRANS_QUINT | 5乗 |
| TRANS_QUART | 4乗 |
| TRANS_QUAD | 2乗 |
| TRANS_EXPO | 指数関数 |
| TRANS_ELASTIC | 弾性 |
| TRANS_CUBIC | 3乗 |
| TRANS_CIRC | 円形 |
| TRANS_BOUNCE | バウンス |
| TRANS_BACK | オーバーシュート |
| TRANS_SPRING | スプリング |

#### EaseType
| 定数 | 説明 |
|------|------|
| EASE_IN | 始点で加速 |
| EASE_OUT | 終点で減速 |
| EASE_IN_OUT | 両端で加減速 |
| EASE_OUT_IN | 中央で加減速 |

### 2.7 シグナル

| シグナル名 | 引数 | 説明 |
|-----------|------|------|
| step_finished | idx: int | ステップ完了時 |
| loop_finished | loop_count: int | ループ完了時 |
| finished | なし | 全体完了時 |

## 3. 処理フロー

### 3.1 Tween実行フロー

```
[create_tween() でTween生成]
      │
      ▼
[tween_property() 等でTweener追加]
      │
      ├─ parallel() → 同じステップに追加
      │
      └─ chain() → 次のステップに追加
      │
      ▼
[自動的に処理開始 (次フレームから)]
      │
      ▼
[_process() / _physics_process() - 毎フレーム]
      │
      ├─ [現在のステップの全Tweenerを更新]
      │       │
      │       ├─ PropertyTweener → プロパティ補間
      │       ├─ MethodTweener → メソッド呼び出し
      │       ├─ IntervalTweener → 待機
      │       └─ CallbackTweener → コールバック実行
      │
      ├─ ステップ完了 → [step_finished シグナル]
      │                      │
      │                      ▼
      │               [次のステップへ]
      │
      └─ 全ステップ完了 → [finished シグナル]
                              │
                              ├─ ループあり → [最初のステップに戻る]
                              │                    │
                              │                    └─ [loop_finished シグナル]
                              │
                              └─ ループなし → [Tween終了]
```

### 3.2 補間計算フロー

```
[PropertyTweener._update()]
      │
      ▼
[経過時間の計算]
      │
      ▼
[イージング関数の適用]
      │
      ├─ transition_type の選択
      │       (LINEAR, SINE, BOUNCE, etc.)
      │
      └─ ease_type の適用
              (IN, OUT, IN_OUT, OUT_IN)
      │
      ▼
[補間値の計算]
      │
      ├─ カスタム補間関数あり → interpolator.call()
      │
      └─ デフォルト → Math::lerp() または Variant::interpolate()
      │
      ▼
[オブジェクトのプロパティを更新]
```

### 3.3 データフロー図

```
[create_tween()]
      │
      ▼
┌─────────────────────────────────────────┐
│               Tween                      │
│  ┌─────────────────────────────────┐    │
│  │     Step 0 (parallel)            │    │
│  │  ┌───────────┐ ┌───────────┐    │    │
│  │  │PropertyTw │ │MethodTw  │    │    │
│  │  └───────────┘ └───────────┘    │    │
│  └─────────────────────────────────┘    │
│                 ↓                        │
│  ┌─────────────────────────────────┐    │
│  │     Step 1                       │    │
│  │  ┌───────────┐                  │    │
│  │  │IntervalTw │                  │    │
│  │  └───────────┘                  │    │
│  └─────────────────────────────────┘    │
│                 ↓                        │
│  ┌─────────────────────────────────┐    │
│  │     Step 2                       │    │
│  │  ┌───────────┐                  │    │
│  │  │CallbackTw │                  │    │
│  │  └───────────┘                  │    │
│  └─────────────────────────────────┘    │
└─────────────────────────────────────────┘
```

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

### 4.1 推奨読解順序

1. **データ構造の理解**
   - `scene/animation/tween.h` (31-200行目): Tweenクラス定義
   - `scene/animation/tween.h` (Tweenerクラス群)

2. **エントリーポイント**
   - `tween.cpp` **_bind_methods()** (32-150行目): GDScriptバインディング
   - `tween.cpp` **tween_property()**: プロパティ補間の開始

3. **コア処理**
   - `tween.cpp` **step()** (340-450行目): フレーム更新処理
   - `tween.cpp` **_calc_delta_val()**: 補間値計算

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

#### step()メソッドの処理（tween.cpp）
```cpp
bool Tween::step(double p_delta) {
    // 経過時間の更新
    // 現在ステップの全Tweenerを更新
    // ステップ完了判定
    // ループ処理
}
```

#### PropertyTweener._update()の処理
- 経過時間からイージング適用後の進行度を計算
- Variant::interpolate()で型に応じた補間を実行
- オブジェクトのset()でプロパティに反映

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

```
SceneTree::process_tweens()
    │
    └── Tween::step(delta)
            │
            ├── _get_delta() - デルタタイム計算
            │
            └── [現在ステップの各Tweener]
                    │
                    ├── PropertyTweener::step()
                    │       │
                    │       ├── _calc_interpolation()
                    │       │       └── run_equation() - イージング計算
                    │       │
                    │       └── object->set(property, value)
                    │
                    ├── MethodTweener::step()
                    │       └── method.call(interpolated_value)
                    │
                    ├── IntervalTweener::step()
                    │       └── (待機のみ)
                    │
                    └── CallbackTweener::step()
                            └── callback.call()

Tween完了時:
    ├── emit_signal("step_finished")
    ├── emit_signal("loop_finished")  // ループ時
    └── emit_signal("finished")       // 完全終了時
```

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

| ファイルパス | 種別 | 役割 |
|-------------|------|------|
| scene/animation/tween.h | ヘッダー | Tween/Tweenerクラス定義 |
| scene/animation/tween.cpp | 実装 | Tween実装 |
| core/math/math_funcs.h | ヘッダー | イージング関数定義 |
| core/variant/variant.h | ヘッダー | Variant::interpolate()定義 |

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

### 5.1 パフォーマンス
- RefCountedベースで自動メモリ管理
- 無効になったTweenは自動的にSceneTreeから削除
- bind_node()でノード削除時の自動停止

### 5.2 使いやすさ
- メソッドチェーンによる直感的なAPI
- デフォルト値で最小限のコードで動作
- Godot 4.0で刷新されたモダンなAPI設計

### 5.3 柔軟性
- カスタム補間関数のサポート
- process/physics両対応
- 相対値・絶対値の切り替え

## 6. 使用例

### 6.1 基本的なプロパティアニメーション
```gdscript
# ノードの位置をアニメーション
var tween = create_tween()
tween.tween_property($Sprite2D, "position", Vector2(400, 300), 1.0)

# イージング付き
tween.tween_property($Sprite2D, "modulate:a", 0.0, 0.5) \
     .set_trans(Tween.TRANS_SINE) \
     .set_ease(Tween.EASE_IN_OUT)
```

### 6.2 シーケンスアニメーション
```gdscript
var tween = create_tween()
# 順番に実行
tween.tween_property($Sprite2D, "position:x", 500, 1.0)
tween.tween_interval(0.5)  # 0.5秒待機
tween.tween_property($Sprite2D, "position:y", 300, 1.0)
tween.tween_callback(func(): print("Animation done!"))
```

### 6.3 並列アニメーション
```gdscript
var tween = create_tween()
tween.set_parallel(true)
# 同時に実行
tween.tween_property($Sprite2D, "position", Vector2(400, 300), 1.0)
tween.tween_property($Sprite2D, "rotation", PI, 1.0)
tween.tween_property($Sprite2D, "scale", Vector2(2, 2), 1.0)
```

### 6.4 ループアニメーション
```gdscript
var tween = create_tween()
tween.set_loops()  # 無限ループ
tween.tween_property($Sprite2D, "modulate:a", 0.5, 0.5)
tween.tween_property($Sprite2D, "modulate:a", 1.0, 0.5)
```

### 6.5 カスタム補間関数
```gdscript
var tween = create_tween()
tween.tween_property($Sprite2D, "position", Vector2(400, 300), 1.0) \
     .set_custom_interpolator(func(p): return p * p * p)  # cubic
```

## 7. 関連機能
- [No.31 AnimationPlayer](./31-AnimationPlayer.md) - キーフレームアニメーション
- [No.32 AnimationTree](./32-AnimationTree.md) - 複雑なアニメーションブレンド
