# 機能設計書: AnimationTree

## 1. 機能概要

### 1.1 機能名
AnimationTree - ブレンドツリーとステートマシンによる複雑なアニメーション制御

### 1.2 機能説明
AnimationTreeは、複数のアニメーションをブレンド・遷移させるための高度なアニメーション制御システムである。ブレンドツリー（BlendTree）やステートマシン（StateMachine）を組み合わせることで、キャラクターの移動速度に応じた歩行・走行のブレンドや、状態遷移に基づくアニメーション切り替えなど、複雑なアニメーションロジックを視覚的に構築できる。

### 1.3 関連画面
- AnimationTreeエディタ
- ブレンドツリーエディタ
- ステートマシンエディタ

## 2. 機能詳細

### 2.1 主要機能一覧

| 機能ID | 機能名 | 説明 |
|--------|--------|------|
| F32-01 | ブレンドツリー処理 | 複数アニメーションの加重ブレンド |
| F32-02 | ステートマシン | 状態に基づくアニメーション遷移 |
| F32-03 | ルートモーション | アニメーションからの移動量抽出 |
| F32-04 | パラメータ制御 | ブレンド量・遷移条件のパラメータ化 |
| F32-05 | ノードグラフ | ビジュアルなノード接続によるロジック構築 |
| F32-06 | ワンショット | 一回再生ノードによる割り込みアニメーション |
| F32-07 | タイムスケール | アニメーション再生速度の動的制御 |

### 2.2 クラス構造

```
AnimationMixer (基底クラス)
    └── AnimationTree (派生クラス)
            │
            ├── AnimationRootNode (ツリールートノード基底)
            │       │
            │       ├── AnimationNodeBlendTree
            │       ├── AnimationNodeStateMachine
            │       └── AnimationNodeAnimation
            │
            └── AnimationNode (ブレンドノード基底)
                    ├── AnimationNodeBlend2
                    ├── AnimationNodeBlend3
                    ├── AnimationNodeBlendSpace1D
                    ├── AnimationNodeBlendSpace2D
                    ├── AnimationNodeOneShot
                    ├── AnimationNodeTimeScale
                    ├── AnimationNodeTimeSeek
                    └── AnimationNodeTransition
```

### 2.3 主要プロパティ

| プロパティ名 | 型 | デフォルト値 | 説明 |
|-------------|-----|-------------|------|
| tree_root | AnimationRootNode | null | ルートノード |
| anim_player | NodePath | "" | AnimationPlayerへのパス |
| advance_expression_base_node | NodePath | "." | 式評価の基準ノード |
| callback_mode_process | int | 1 | 処理コールバックモード |
| callback_mode_method | int | 0 | メソッドコールバックモード |
| callback_mode_discrete | int | 1 | 離散コールバックモード |

### 2.4 主要メソッド

| メソッド名 | 戻り値 | 説明 |
|-----------|--------|------|
| set(parameter, value) | void | パラメータ値を設定 |
| get(parameter) | Variant | パラメータ値を取得 |
| get_root_motion_position() | Vector3 | ルートモーションの位置変化を取得 |
| get_root_motion_rotation() | Quaternion | ルートモーションの回転変化を取得 |
| get_root_motion_scale() | Vector3 | ルートモーションのスケール変化を取得 |
| get_root_motion_position_accumulator() | Vector3 | 累積位置変化を取得 |
| get_root_motion_rotation_accumulator() | Quaternion | 累積回転変化を取得 |
| get_root_motion_scale_accumulator() | Vector3 | 累積スケール変化を取得 |

### 2.5 AnimationNodeの種類

| ノード名 | 説明 |
|---------|------|
| AnimationNodeAnimation | 単一アニメーション再生 |
| AnimationNodeBlend2 | 2つのアニメーションをブレンド |
| AnimationNodeBlend3 | 3つのアニメーションをブレンド |
| AnimationNodeBlendSpace1D | 1次元ブレンドスペース |
| AnimationNodeBlendSpace2D | 2次元ブレンドスペース |
| AnimationNodeOneShot | ワンショットアニメーション |
| AnimationNodeStateMachine | ステートマシン |
| AnimationNodeTimeScale | 再生速度制御 |
| AnimationNodeTimeSeek | 再生位置制御 |
| AnimationNodeTransition | 状態遷移ノード |
| AnimationNodeAdd2 | アディティブブレンド（2入力） |
| AnimationNodeAdd3 | アディティブブレンド（3入力） |
| AnimationNodeSub2 | サブトラクティブブレンド |

### 2.6 シグナル

| シグナル名 | 引数 | 説明 |
|-----------|------|------|
| animation_player_changed | なし | AnimationPlayer変更時 |
| animation_started | anim_name | アニメーション開始時 |
| animation_finished | anim_name | アニメーション終了時 |

## 3. 処理フロー

### 3.1 ブレンドツリー処理フロー

```
[_process_animation() - 毎フレーム]
      │
      ▼
[tree_root.process() 呼び出し]
      │
      ▼
[AnimationNodeBlendTree.process()]
      │
      ├─ [各子ノードのprocess()を再帰呼び出し]
      │       │
      │       ├─ AnimationNodeAnimation → アニメーションデータ取得
      │       │
      │       ├─ AnimationNodeBlend2 → 2入力ブレンド
      │       │       └─ blend_input(0) * (1-amount) + blend_input(1) * amount
      │       │
      │       └─ AnimationNodeBlendSpace2D → 2D座標に基づくブレンド
      │               └─ 三角形補間によるウェイト計算
      │
      ▼
[ブレンド結果をtrack_cacheに格納]
      │
      ▼
[_apply_animation() でノードに適用]
```

### 3.2 ステートマシン処理フロー

```
[AnimationNodeStateMachine.process()]
      │
      ▼
[現在状態のアニメーション処理]
      │
      ▼
[遷移条件チェック]
      │
      ├─ 条件成立 → [遷移処理開始]
      │                    │
      │                    ▼
      │              [クロスフェード/即時遷移]
      │                    │
      │                    ▼
      │              [新状態へ移行]
      │
      └─ 条件不成立 → [現在状態継続]
```

### 3.3 データフロー図

```
[パラメータ入力]          [AnimationLibrary]
   (blend_amount,             │
    travel_to, etc.)          │
        │                     ▼
        ▼              ┌─────────────────┐
   ┌─────────┐         │ AnimationPlayer │
   │ パラメータ│         │  (animation_set)│
   │  マップ  │         └─────────────────┘
   └─────────┘                  │
        │                       ▼
        │              ┌──────────────────┐
        └─────────────→│  AnimationTree   │
                       │                  │
                       │  ┌────────────┐  │
                       │  │ tree_root  │  │
                       │  │ (BlendTree │  │
                       │  │   / State  │  │
                       │  │   Machine) │  │
                       │  └────────────┘  │
                       └──────────────────┘
                                │
                                ▼
                       [ブレンド済みポーズ]
                                │
                                ▼
                       [ターゲットノード]
```

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

### 4.1 推奨読解順序

1. **データ構造の理解**
   - `scene/animation/animation_tree.h` (31-200行目): AnimationTreeクラス定義
   - `scene/animation/animation_node.h`: AnimationNodeクラス定義

2. **エントリーポイント**
   - `animation_tree.cpp` **_bind_methods()**: GDScriptバインディング
   - `animation_tree.cpp` **_process()**: メイン処理ループ

3. **コア処理**
   - `animation_tree.cpp` **_process_animation()**: アニメーション処理
   - `animation_blend_tree.cpp`: ブレンドツリー処理
   - `animation_node_state_machine.cpp`: ステートマシン処理

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

#### tree_root.process()のブレンド処理
```cpp
// AnimationNodeBlend2の場合
double blend_input(int p_input, double p_time, bool p_seek,
                   bool p_is_external_seeking, real_t p_blend,
                   FilterAction p_filter = FILTER_IGNORE,
                   bool p_sync = true, real_t *r_max = nullptr)
```

#### ルートモーション抽出
- `root_motion_track`プロパティで指定したトラックから移動量を抽出
- `get_root_motion_position()`で位置差分を取得
- キャラクターコントローラーと連携して物理的な移動に反映

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

```
AnimationTree::_process()
    │
    ├── AnimationMixer::_check_process()
    │
    └── AnimationTree::_process_animation()
            │
            ├── tree_root->process()
            │       │
            │       ├── AnimationNodeBlendTree::_process()
            │       │       │
            │       │       ├── AnimationNodeOutput::process()
            │       │       │
            │       │       └── [子ノード].blend_input()
            │       │               │
            │       │               ├── AnimationNodeAnimation::process()
            │       │               │       └── _get_animation()
            │       │               │
            │       │               └── AnimationNodeBlend2::process()
            │       │                       └── 補間計算
            │       │
            │       └── AnimationNodeStateMachine::_process()
            │               │
            │               ├── _travel()
            │               │       └── 遷移パス計算
            │               │
            │               └── _update_current()
            │                       └── 状態更新
            │
            └── AnimationMixer::_apply_animation()
                    └── _apply_track_value()
```

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

| ファイルパス | 種別 | 役割 |
|-------------|------|------|
| scene/animation/animation_tree.h | ヘッダー | AnimationTreeクラス定義 |
| scene/animation/animation_tree.cpp | 実装 | AnimationTreeの実装 |
| scene/animation/animation_node.h | ヘッダー | AnimationNode基底クラス |
| scene/animation/animation_blend_tree.h | ヘッダー | ブレンドツリーノード定義 |
| scene/animation/animation_blend_tree.cpp | 実装 | ブレンドツリー実装 |
| scene/animation/animation_node_state_machine.h | ヘッダー | ステートマシン定義 |
| scene/animation/animation_node_state_machine.cpp | 実装 | ステートマシン実装 |
| scene/animation/animation_blend_space_1d.h | ヘッダー | 1Dブレンドスペース |
| scene/animation/animation_blend_space_2d.h | ヘッダー | 2Dブレンドスペース |

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

### 5.1 パフォーマンス
- ノードグラフの効率的な走査
- ブレンドウェイトが0のノードのスキップ
- キャッシュによる重複計算の回避

### 5.2 拡張性
- カスタムAnimationNodeの作成が可能
- `_process()`メソッドのオーバーライドで独自ブレンドロジック実装
- 新しいブレンドモードの追加が容易

### 5.3 デバッグ支援
- エディタでのリアルタイムプレビュー
- パラメータの動的変更と確認
- ステートマシンの状態可視化

## 6. 使用例

### 6.1 ブレンドツリーでの移動アニメーション
```gdscript
@onready var anim_tree = $AnimationTree

func _physics_process(delta):
    var velocity = $CharacterBody3D.velocity
    var speed = velocity.length()

    # ブレンドパラメータを設定
    anim_tree.set("parameters/BlendSpace1D/blend_position", speed / max_speed)
```

### 6.2 ステートマシンでの状態遷移
```gdscript
@onready var anim_tree = $AnimationTree
@onready var state_machine = anim_tree.get("parameters/StateMachine/playback")

func jump():
    state_machine.travel("Jump")

func land():
    state_machine.travel("Idle")

func _on_attack_pressed():
    # OneShotノードを使用した攻撃アニメーション
    anim_tree.set("parameters/AttackOneShot/request", AnimationNodeOneShot.ONE_SHOT_REQUEST_FIRE)
```

### 6.3 ルートモーションの適用
```gdscript
@onready var anim_tree = $AnimationTree
@onready var character = $CharacterBody3D

func _physics_process(delta):
    # ルートモーションから移動量を取得
    var root_motion = anim_tree.get_root_motion_position()

    # キャラクターに適用
    character.velocity = root_motion / delta
    character.move_and_slide()
```

## 7. 関連機能
- [No.31 AnimationPlayer](./31-AnimationPlayer.md) - 基本的なアニメーション再生
- [No.34 スケルトン/ボーン](./34-スケルトン_ボーン.md) - 骨格アニメーション
