# 画面設計書 43-アニメーションツリーエディタ

## 概要

本ドキュメントは、Godot Engineエディタにおけるアニメーションツリーエディタ（AnimationTreeEditor）の画面設計書である。AnimationTreeノードのルートアニメーションノードを編集するためのエディタ画面の仕様を定義する。

### 本画面の処理概要

アニメーションツリーエディタは、AnimationTreeのルートアニメーションノード（BlendTree、StateMachine、BlendSpace1D、BlendSpace2D）を編集するための専用エディタである。階層的なアニメーションノード構造をナビゲートしながら、各ノードタイプに応じた専用エディタで編集を行う。

**業務上の目的・背景**：ゲーム開発においてキャラクターアニメーションは複雑なブレンドや状態遷移を必要とする。AnimationTreeはこれらを階層的なノード構造で管理するが、その設定は複雑になりがちである。本エディタは、ノードタイプに応じた専用のビジュアルエディタを提供し、直感的なアニメーション制御の設定を可能にする。パスナビゲーションにより深い階層構造でも迷わず編集できる。

**画面へのアクセス方法**：シーン内のAnimationTreeノードを選択すると、エディタ下部のドックパネルにAnimationTreeエディタが表示される。ショートカットキーでのトグル表示も可能。

**主要な操作・処理内容**：
1. パスナビゲーション：Root/子ノード名のボタンで編集対象を切り替え
2. BlendTreeエディタ：GraphEditベースでノードグラフを編集
3. StateMachineエディタ：ステートマシンの状態と遷移を編集
4. BlendSpace1D/2Dエディタ：ブレンドスペースの設定を編集
5. ノード追加・削除：各エディタで対応するノードを追加・削除
6. 接続編集：ノード間の接続を作成・削除
7. プロパティ編集：各ノードのパラメータをインスペクタで編集

**画面遷移**：AnimationTreeEditorはEditorDockとして実装され、下部ドックまたはフローティングウィンドウとして表示される。enter_editor()で子ノードの編集に入り、パスボタンで上位階層に戻る。

**権限による表示制御**：エディタ機能のため、特定の権限制御は存在しない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| F-043 | アニメーション編集 | 主機能 | AnimationTreeのノード構造編集 |
| - | AnimationNodeBlendTreeEditor | 補助機能 | BlendTreeノード専用エディタ |
| - | AnimationNodeStateMachineEditor | 補助機能 | StateMachineノード専用エディタ |
| - | AnimationNodeBlendSpace1DEditor | 補助機能 | BlendSpace1D専用エディタ |
| - | AnimationNodeBlendSpace2DEditor | 補助機能 | BlendSpace2D専用エディタ |
| - | EditorUndoRedoManager | 補助機能 | 編集操作のUndo/Redo対応 |

## 画面種別

ドックパネル（プラグインベースエディタ）

## URL/ルーティング

該当なし（エディタドックとして実装）

## 入出力項目

### 入力項目

| 項目名 | 項目ID | データ型 | 必須 | 入力形式 | バリデーション | 説明 |
|--------|--------|----------|------|----------|----------------|------|
| AnimationTree | tree | AnimationTree* | 必須 | ノード参照 | 有効なAnimationTree | 編集対象のAnimationTreeノード |

### 出力項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| 編集済みAnimationTree | AnimationTree* | ノード構造が更新されたAnimationTree |

## 表示項目

### パスナビゲーションエリア

| 項目名 | 項目ID | データ型 | 説明 |
|--------|--------|----------|------|
| パスラベル | - | Label | "Path:" 固定ラベル |
| パススクロール | path_edit | ScrollContainer | パスボタン群のスクロールコンテナ |
| パスボタン群 | path_hb | HBoxContainer | Root + 各階層ボタン |

### エディタベースエリア

| 項目名 | 項目ID | データ型 | 説明 |
|--------|--------|----------|------|
| エディタコンテナ | editor_base | MarginContainer | プラグインエディタの表示領域 |

### BlendTreeエディタ（AnimationNodeBlendTreeEditor）

| 項目名 | 項目ID | データ型 | 説明 |
|--------|--------|----------|------|
| グラフエディタ | graph | GraphEdit | ノードグラフ表示領域 |
| ノード追加メニュー | add_node | MenuButton | ノード追加メニュー |
| エラーパネル | error_panel | PanelContainer | エラー表示パネル |
| エラーラベル | error_label | Label | エラーメッセージ表示 |
| フィルタダイアログ | filter_dialog | AcceptDialog | ボーンフィルタ設定ダイアログ |
| フィルタツリー | filters | Tree | フィルタ対象ボーン一覧 |

### StateMachineエディタ（AnimationNodeStateMachineEditor）

| 項目名 | 項目ID | データ型 | 説明 |
|--------|--------|----------|------|
| 選択ツール | tool_select | Button | 選択モード切替 |
| 作成ツール | tool_create | Button | ノード作成モード切替 |
| 接続ツール | tool_connect | Button | 接続作成モード切替 |
| 削除ツール | tool_erase | Button | 選択削除 |
| 遷移モード | switch_mode | OptionButton | 遷移切替モード選択 |
| 自動進行 | auto_advance | Button | 自動進行設定 |
| 再生モード | play_mode | OptionButton | 再生モード選択 |
| 描画エリア | state_machine_draw | Control | ステートマシン描画領域 |
| 再生位置表示 | state_machine_play_pos | Control | 再生位置オーバーレイ |

## イベント仕様

### 1-パスボタン押下イベント

**トリガー**: パスナビゲーションのボタン押下

**処理内容**:
1. 押下されたボタンのインデックスを取得
2. edited_pathをそのインデックスまでに切り詰め
3. edit_path()を呼び出して対象ノードを変更
4. 対応するエディタプラグインを表示

**関連メソッド**: `_path_button_pressed()` (L76-81)

### 2-エディタ階層移動イベント

**トリガー**: 子ノードのダブルクリック、enter_editor()呼び出し

**処理内容**:
1. 現在のedited_pathに子ノード名を追加
2. edit_path()で新しいパスを設定
3. 子ノードタイプに応じたエディタを表示
4. パスナビゲーションを更新

**関連メソッド**: `enter_editor()` (L172-176)

### 3-BlendTree ノード追加イベント

**トリガー**: add_nodeメニューからノード選択

**処理内容**:
1. 選択されたノードタイプをインスタンス化
2. Undo/Redoアクションを作成
3. BlendTreeにノードを追加
4. グラフを更新

**関連メソッド**: `AnimationNodeBlendTreeEditor::_add_node()` (L95)

### 4-BlendTree ノード接続イベント

**トリガー**: 出力ポートから入力ポートへのドラッグ

**処理内容**:
1. 接続の有効性を確認
2. Undo/Redoアクションを作成
3. BlendTreeに接続を登録
4. グラフを再描画

**関連メソッド**: `AnimationNodeBlendTreeEditor::_connection_request()` (L109)

### 5-StateMachine ステート作成イベント

**トリガー**: tool_createモードでキャンバスクリック

**処理内容**:
1. クリック位置を取得
2. ノード追加メニューを表示
3. ノード選択後、指定位置にステートを追加
4. ステートマシンを再描画

**関連メソッド**: `AnimationNodeStateMachineEditor::_add_menu_type()` (L181)

### 6-StateMachine 遷移作成イベント

**トリガー**: tool_connectモードでステート間をドラッグ

**処理内容**:
1. 接続元ステートを記録
2. ドラッグ中は接続線をプレビュー表示
3. 接続先ステートでドロップ時に遷移を作成
4. 遷移プロパティダイアログを表示

**関連メソッド**: `AnimationNodeStateMachineEditor::_add_transition()` (L236)

### 7-アニメーションリスト変更イベント

**トリガー**: AnimationTreeのanimation_list_changedシグナル

**処理内容**:
1. BlendTreeエディタのupdate_graph()を呼び出し
2. AnimationNodeAnimationのドロップダウンを更新

**関連メソッド**: `_animation_list_changed()` (L83-88)

### 8-ルートノード変更監視イベント

**トリガー**: NOTIFICATION_PROCESS

**処理内容**:
1. 現在のルートノードIDを取得
2. 変更があればedit_path(空)でリセット
3. パス長が変更されていれば再編集

**関連メソッド**: `_notification(NOTIFICATION_PROCESS)` (L180-193)

## データベース更新仕様

### 操作別データベース影響一覧

本画面はデータベースを使用せず、シーンファイル（.tscn/.scn）内のAnimationTreeリソースを更新する。

| 操作（イベント） | 対象データ | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| BlendTreeノード追加 | AnimationNodeBlendTree.nodes | INSERT | ブレンドノードを追加 |
| BlendTreeノード削除 | AnimationNodeBlendTree.nodes | DELETE | ブレンドノードを削除 |
| BlendTree接続追加 | AnimationNodeBlendTree.connections | INSERT | ノード間接続を追加 |
| StateMachineステート追加 | AnimationNodeStateMachine.states | INSERT | ステートを追加 |
| StateMachine遷移追加 | AnimationNodeStateMachine.transitions | INSERT | 遷移を追加 |
| ノード位置変更 | AnimationNode.position | UPDATE | グラフ上の位置を更新 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| - | ラベル | "Path:" | パスナビゲーション先頭 |
| - | ボタン | "Root" | パスナビゲーションルートボタン |
| - | ショートカット名 | "Toggle AnimationTree Dock" | コマンドパレット表示 |
| - | ドック名 | "AnimationTree" | ドックタブ表示名 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|----------|
| AnimationTreeノード削除 | _node_removed()でtreeをnullに設定、エディタをクリア |
| ルートアニメーションノード未設定 | 各エディタを非表示、空のパスで表示 |
| 無効な子ノードパス | ERR_BREAKで中断、パスをその時点までに設定 |
| メインスレッド外からのアニメーションリスト取得 | 空のベクターを返却 |

## 備考

- AnimationTreeEditorはEditorDockを継承し、下部ドックまたはフローティングとして表示可能
- 4種類のエディタプラグイン（BlendTree、StateMachine、BlendSpace1D、BlendSpace2D）を内蔵
- プラグイン方式により、can_edit()で対応可能なノードタイプを判定
- シングルトンパターンで実装され、静的get_animation_list()関数を提供
- set_process()でフレーム毎にルートノード変更を監視
- 最小サイズは300ピクセル（エディタスケール適用後）

---

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

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

### 推奨読解順序

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

AnimationTreeと各種AnimationNodeの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | animation_tree.h | `scene/animation/animation_tree.h` | AnimationTreeクラス、get_root_animation_node() |
| 1-2 | animation_tree_editor_plugin.h | `editor/animation/animation_tree_editor_plugin.h` | AnimationTreeEditor、AnimationTreeNodeEditorPlugin基底クラス |

**読解のコツ**: AnimationTreeNodeEditorPluginは抽象基底クラスであり、can_edit()とedit()を各プラグインがオーバーライドする。

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

エディタの初期化とプラグイン登録を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | animation_tree_editor_plugin.cpp | `editor/animation/animation_tree_editor_plugin.cpp` | コンストラクタ（L261-294）でUI構築とプラグイン登録 |

**主要処理フロー**:
1. **L261-263**: シングルトン設定、get_animation_list関数ポインタ設定
2. **L265-271**: EditorDock設定（名前、アイコン、ショートカット、レイアウト）
3. **L273-288**: UI構築（VBoxContainer、ScrollContainer、HBoxContainer）
4. **L290-293**: プラグイン登録（BlendTree、BlendSpace1D、BlendSpace2D、StateMachine）

#### Step 3: パスナビゲーションを理解する

階層移動の仕組みを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | animation_tree_editor_plugin.cpp | `editor/animation/animation_tree_editor_plugin.cpp` | edit_path()（L119-155）、enter_editor()（L172-176） |

**主要処理フロー**:
- **L122-132**: ルートから指定パスまでノードを辿る
- **L136-144**: 各プラグインのcan_edit()をチェックし、該当するものを表示
- **L154**: _update_path()でUIを更新

#### Step 4: BlendTreeエディタを理解する

GraphEditベースのBlendTree編集を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | animation_blend_tree_editor_plugin.h | `editor/animation/animation_blend_tree_editor_plugin.h` | AnimationNodeBlendTreeEditorクラス定義 |
| 4-2 | animation_blend_tree_editor_plugin.cpp | `editor/animation/animation_blend_tree_editor_plugin.cpp` | GraphEdit操作、ノード追加・接続処理 |

**主要処理フロー**:
- GraphEdit使用（graph メンバ）
- MenuButtonでノード追加（add_node）
- フィルタダイアログでボーンフィルタ設定

#### Step 5: StateMachineエディタを理解する

ステートマシン専用の描画と操作を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | animation_state_machine_editor.h | `editor/animation/animation_state_machine_editor.h` | AnimationNodeStateMachineEditorクラス定義、ThemeCache、NodeRect、TransitionLine |

**主要処理フロー**:
- 独自のControlベース描画（state_machine_draw）
- ツールボタンで操作モード切替（select/create/connect/erase）
- 遷移設定（switch_mode、auto_advance）

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

```
AnimationTreeEditorPlugin::edit()
    │
    └─ AnimationTreeEditor::edit()
           │
           ├─ animation_list_changed シグナル接続
           │
           └─ edit_path([]) [初期パスで編集開始]
                  │
                  ├─ get_root_animation_node()
                  │
                  ├─ get_child_by_name() [パス辿り]
                  │
                  ├─ [各プラグイン].can_edit() チェック
                  │      ├─ AnimationNodeBlendTreeEditor
                  │      ├─ AnimationNodeStateMachineEditor
                  │      ├─ AnimationNodeBlendSpace1DEditor
                  │      └─ AnimationNodeBlendSpace2DEditor
                  │
                  ├─ [該当プラグイン].edit() → show()
                  │
                  └─ _update_path() [パスUI更新]

[ユーザー操作]
    │
    ├─ _path_button_pressed() [パスボタン押下]
    │      └─ edit_path() [新しいパスで編集]
    │
    └─ enter_editor() [子ノード編集に入る]
           └─ edit_path() [パスに追加して編集]
```

### データフロー図

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

AnimationTree              ─────▶ edit()                     ─────▶ エディタ表示
  - root_animation_node          └─ edit_path()                     └─ プラグインUI

パスボタン押下            ─────▶ _path_button_pressed()     ─────▶ edit_path()
                                 └─ edited_path更新                  └─ プラグイン切替

animation_list_changed     ─────▶ _animation_list_changed()  ─────▶ update_graph()
シグナル                                                            └─ ノードUI更新

NOTIFICATION_PROCESS       ─────▶ current_root比較           ─────▶ edit_path(空)
                                 └─ ルート変更検知                   └─ リセット
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| animation_tree_editor_plugin.cpp | `editor/animation/animation_tree_editor_plugin.cpp` | ソース | メインエディタ実装 |
| animation_tree_editor_plugin.h | `editor/animation/animation_tree_editor_plugin.h` | ヘッダ | メインエディタ定義 |
| animation_blend_tree_editor_plugin.cpp | `editor/animation/animation_blend_tree_editor_plugin.cpp` | ソース | BlendTreeエディタ実装 |
| animation_blend_tree_editor_plugin.h | `editor/animation/animation_blend_tree_editor_plugin.h` | ヘッダ | BlendTreeエディタ定義 |
| animation_state_machine_editor.cpp | `editor/animation/animation_state_machine_editor.cpp` | ソース | StateMachineエディタ実装 |
| animation_state_machine_editor.h | `editor/animation/animation_state_machine_editor.h` | ヘッダ | StateMachineエディタ定義 |
| animation_blend_space_1d_editor.cpp | `editor/animation/animation_blend_space_1d_editor.cpp` | ソース | BlendSpace1Dエディタ実装 |
| animation_blend_space_2d_editor.cpp | `editor/animation/animation_blend_space_2d_editor.cpp` | ソース | BlendSpace2Dエディタ実装 |
| animation_tree.h | `scene/animation/animation_tree.h` | ヘッダ | AnimationTreeクラス定義 |
| animation_blend_tree.h | `scene/animation/animation_blend_tree.h` | ヘッダ | AnimationNodeBlendTree定義 |
| animation_node_state_machine.h | `scene/animation/animation_node_state_machine.h` | ヘッダ | AnimationNodeStateMachine定義 |
| editor_dock.h | `editor/docks/editor_dock.h` | ヘッダ | EditorDock基底クラス |
