Spec
機能仕様書: SerializeField 値更新ツール
機能ID: SPEC-0b6b106c
作成日: 2025-11-07
ステータス: 下書き
入力: ユーザー説明: "Scene/prefab SerializeField update tooling"
ユーザーシナリオ&テスト (必須)
ユーザーストーリー1 - シーン内SerializeFieldを正確に更新したい (優先度: P1)
レベルデザイナーがMCPクライアントからシーン内のGameObjectを指定し、非公開のSerializeField値を正確に変更したい。値変更はUndoや再実行ができ、ヒエラルキーの位置を壊さずに安全に適用される必要がある。
この優先度の理由: LLMオペレーションの主目的がシーン調整であり、人手介入を省略できると制作時間を大幅に削減できるため。
独立テスト: 任意のシーンGameObjectに対して単一フィールド更新を指示し、レスポンスが旧値と新値を返しつつ、実際のUnityシーンで値が置き換わることを確認すれば完了。
受け入れシナリオ:
- 前提 シーンにSerializeFieldを持つコンポーネントがある、実行 GameObjectパス・コンポーネント種別・フィールド名と値を指定して更新を要求、結果 Unity上の値が即時に更新されレスポンスが成功・旧値・新値・保存要否を含む。
- 前提 Play Mode中で構造変更が禁止されている、実行 runtime意図がないまま変更を要求、結果 レスポンスが「Play中はruntime指定必須」の明確なエラーを返す。
ユーザーストーリー2 - Prefab資産をバッチ調整したい (優先度: P2)
テクニカルアーティストがPrefab資産を複数まとめて調整する際、Unityを手動で開かずにMCPからSerializeField値を変更したい。変更後はPrefab保存状態が明示され、必要に応じて差分をプレビューしたい。
この優先度の理由: Prefab調整は繰り返し作業であり、遠隔更新により作業時間とエラーを削減できるため。
独立テスト: 任意のPrefab資産に対して更新コマンドを発行し、レスポンスに保存状況と必要な後処理(保存済/保存待ち)が含まれるかを検証する。
受け入れシナリオ:
- 前提 保存済Prefabが存在する、実行 Prefabパスと内部オブジェクト指定で値更新を要求、結果 レスポンスが旧値・新値・Prefab保存可否・必要なフォローアップを返す。
ユーザーストーリー3 - 変更前検証だけを実行したい (優先度: P3)
QAオペレーターが安全性のために「適用せず検証のみ」を実行し、ターゲット解決が正しいかを確かめたい。dry-run結果により、影響範囲が安全であると判断できる。
この優先度の理由: 誤更新によるPrefab破損を避けられ、規模の大きいチームで承認フローを組みやすいため。
独立テスト: dry-runフラグを立ててコマンドを実行し、Unity上の値が変わらずレスポンスだけにプレビュー値が含まれることを確認する。
受け入れシナリオ:
- 前提 ターゲットが存在する、実行 dry-run付きで更新を要求、結果 レスポンスに「dryRun: true」「previewValue」が含まれ、Unity上の値はそのまま。
エッジケース
- GameObjectパスやPrefab内部パスが存在しない場合は、人が即座に判断できるエラー文を返し、候補やデバッグ情報を含める。
- Play Mode中に許可されない操作を指示した場合、Play Mode用パラメータの要否を示す警告で止める。
- enum・配列・構造体など複合フィールドに対して誤ったインデックスや値を渡した場合、破壊的変更を行わず詳細な検証メッセージを返す。
- 参照対象のPrefabが編集中/ロック中の場合、競合状態を知らせ、ユーザーが作業モードを切り替えられるようにする。
要件 (必須)
機能要件
- FR-001: ユーザーはシーンGameObjectまたはPrefab資産をパス指定し、SerializeField値を単発で更新できる。
- FR-002: 操作結果は旧値・新値・対象パス・追加アクション(保存/適用/再確認)を含む要約を返す。
- FR-003: dry-run指定時はUnityオブジェクトを変更せず、ターゲット解析結果とプレビュー値を返す。
- FR-004: Play Mode中のガード(runtime指定・構造変更制限など)を自動適用し、違反時は安全にブロックする。
- FR-005: Prefab資産を編集した際は保存/未保存状態を示し、必要なら保存を自動実行またはユーザーに指示する。
- FR-006: 参照型や列挙型に対し、存在しないエントリを指定した場合は明確な理由を付けて失敗させる。
- FR-007: すべての操作が履歴に残り、いつ誰がどのフィールドを変更したかを追跡できる。
- [要明確化] ログの保持期間と閲覧権限は別途決定が必要。
主要エンティティ
- SerializeField 更新リクエスト: ターゲットパス、コンポーネント種別、フィールドパス、値、dry-run/保存フラグを含む。レスポンス要素を定義する元データ。
- ターゲットオブジェクト: シーン内GameObjectまたはPrefab内部オブジェクト。ヒエラルキー情報、所属シーン/Prefab、Dirty状態などを持つ。
スコープ外 (オプション)
- コード生成やスクリプト編集によるSerializeField追加/削除。
- 複数フィールドを一括更新するバッチ処理。
- 依存スクリプトの再コンパイルや差分ビルドの自動化。
技術制約 (該当する場合)
- 対応Unityバージョンは2021LTS〜2023LTSのエディタ環境に限定する。
- MCPサーバ経由のリクエストは順序性が保証され、同一ターゲットへの競合更新はクライアント側でシリアル化される前提とする。
前提条件 (該当する場合)
- UnityプロジェクトにはPrefab Stage編集機能が有効であり、対象Prefabsはローカルファイルとしてアクセスできる。
- MCPクライアントはGameObjectパスやPrefabパスを取得できる既存のヒエラルキー/コンポーネント閲覧ツールを利用できる。
依存関係 (該当する場合)
- 既存の
get_hierarchy、list_components、get_component_values などのツールから得られるパス・フィールド情報。
- MCPコマンド履歴/監査ログの永続化仕組み。
成功基準 (必須)
- シーンおよびPrefabを対象にした代表的なSerializeField更新タスク(各5件)が、MCP経由で100%完了し追加の手作業を要さない。
- dry-run機能を通じて、存在しないターゲットや型不一致を100%検出できる。
- Prefab更新後の保存漏れによる差分消失が0件である。
Plan
実装計画: SerializeField 値更新ツール
機能ID: SPEC-0b6b106c | 日付: 2025-11-07 | 仕様: spec.md
入力: /specs/SPEC-0b6b106c/spec.md の機能仕様
実行フロー (/speckit.plan コマンドのスコープ)
1. 入力仕様を読み込み ✅
2. 技術コンテキストを記入 ✅
3. 憲章チェック (初回) ✅
4. Phase 0: research.md で未確定事項を解消 → 実施予定
5. Phase 1: data-model.md / contracts/ / quickstart.md を作成 → 実施予定
6. 憲章チェック (設計後) → Phase1完了後に再実施
7. Phase 2: タスク生成方針を本計画に記述 ✅
8. /speckit.tasks 実行待ち
概要
シーン/Prefabに紐づくSerializeFieldをリモートから安全に更新できるMCPツールを追加する。ユーザーはGameObjectパスまたはPrefab資産パスを指定して単一フィールドを更新し、dry-run・旧値/新値・保存要否・エラー理由を受け取る。Play Mode中の制約、Prefab Stage、オブジェクト参照、配列/enumなどの特例を標準化し、Undo/ログポリシーを含めて自動操作の安全性を確保する。
技術コンテキスト
言語/バージョン: Node.js 18.x (ESM) / C# 9 + Unity 2021LTS〜2023LTS
主要依存関係: MCP SDK, better-sqlite3 (既存), UnityEditor API (SerializedObject/PrefabUtility)
ストレージ: 既存のMCP設定/ログ+Unity项目ファイル (追加永続化なし)
テスト: Node.js node --test、Unity Editor Test Runner (EditMode)
対象プラットフォーム: デスクトップOS上のUnity Editor + Node CLI
プロジェクトタイプ: multi (unity-cli + Unityパッケージ)
パフォーマンス目標: 単一フィールド更新を1秒以内に完了、dry-runは500ms以内で応答
制約: Play Modeではruntime:true指定時のみ許可、Prefab編集時は保存手順を必ず提示
スケール/スコープ: 10^3 GameObjects / 10^2 Prefab資産の運用を想定
憲章チェック
シンプルさ:
- プロジェクト数: 2 (Nodeサーバー, Unityパッケージ) → 既存構造に追従 ✅
- フレームワーク直使用: NodeはMCP SDKを直接利用 / UnityはEditor API直接利用 ✅
- 単一データモデル:
ComponentFieldUpdateRequest と SerializeFieldResult の2つに統一予定 ✅
- 余計なパターンなし (Repository/UoW等は導入しない) ✅
アーキテクチャ:
- 既存BaseToolHandler + ComponentHandlerへの拡張のみ。新規ライブラリは不要 ✅
- CLI/ツールドキュメント: README + spec/plan に追記しLLM向けクイックスタートで周知 ✅
テスト (妥協不可):
- RED→GREEN→リファクタを厳守。まずNode側ハンドラテスト (RED)→実装→Unity側EditModeテストの順 ✅
- Contract→Integration→Unit順: Nodeハンドラはcontract的テスト、Unity側はintegrationテストでGameplay環境を模倣 ✅
- 実依存関係を使用(Unity Editor実オブジェクト、実Prefabロード) ✅
- テスト前の実装/REDスキップは禁止 (チェックリストに追記) ✅
可観測性:
- 既存loggerに
set_component_fieldカテゴリーを追加し、対象パス/結果/エラーを構造化出力 ✅
- エラー時は旧値を返すことで診断性を確保 ✅
バージョニング:
- npmパッケージはMINORアップデート予定 (新機能)。Unityパッケージは
package.json のpatchアップデート記録を追加 ✅
- 破壊的変更なし (既存ツールに影響しない) ✅
プロジェクト構造
ドキュメント
specs/SPEC-0b6b106c/
├── spec.md # 機能仕様 (完了)
├── plan.md # このファイル
├── research.md # Phase 0: API/ガード条件の調査 (作成予定)
├── data-model.md # Phase 1: リクエスト/レスポンス構造 (作成予定)
├── quickstart.md # Phase 1: LLM向け手順 (作成予定)
├── contracts/ # Nodeハンドラインターフェイス契約 (作成予定)
└── tasks.md # /speckit.tasks で生成予定
ソースコード
unity-cli/
├── src/handlers/component/ComponentFieldSetToolHandler.js # 新規ハンドラ
├── tests/unit/handlers/component/ComponentFieldSetToolHandler.test.js # RED→GREEN
└── README.md (ツール一覧更新)
UnityCliBridge/Packages/unity-cli-bridge/
├── Editor/Handlers/ComponentHandler.cs # SerializedProperty更新ロジックを追加
├── Editor/Core/UnityCliBridge.cs # 新コマンドルーティング
└── Tests/Editor/Handlers/ComponentHandlerTests.cs # Prefab/シーン/EditModeテスト
Phase 0: アウトライン&リサーチ
-
未確定事項
- Prefab Stage vs Prefab資産 vs シーンの判定アルゴリズム
- enum/配列/参照型のSerializeFieldパス表記 (dot,
Array.data[x] 等)
- Play Mode中の安全ガード (runtimeパラメータの意味)
- dry-run結果フォーマット (previewValueの扱い)
-
リサーチタスク (research.mdに記録)
- Unity Editor API: SerializedObject/SerializedPropertyの最新制約
- PrefabUtility.SavePrefabAsset vs ApplyPrefabInstance のベストプラクティス
- Undo/Redoとログ出力の連携 (Unity Guidelines)
- オブジェクト参照をGUID/AssetPathで受け取る際のセキュリティ考慮
-
リサーチ成果の書式
- 決定 / 理由 / 代替案を箇条書きで記載
- すべての要明確化タグを解消してからPhase1へ進む
Phase 1: 設計&契約
-
data-model.md
ComponentFieldUpdateRequest
scope, gameObjectPath, prefabAssetPath, componentType, fieldPath, valueType, value, enumValue, objectReference, dryRun, applyPrefabChanges, createUndo, markSceneDirty
ComponentFieldUpdateResult
scope, gameObjectPath, prefabAssetPath, serializedPropertyPath, previousValue, appliedValue, requiresSave, notes[], dryRun
- 検証ルール (必須/相互排他/型制約)
-
contracts/
set_component_field.request.json / set_component_field.response.json (JSON Schema) を追加
- NodeハンドラがUnityコマンドに渡すPayload契約を明示
-
quickstart.md
- LLMがツールを呼び出すためのステップ: パス取得→dry-run→本適用→保存確認
- 事前条件: GameObjectパス確認方法、Prefab Stageの確認手順
-
Unity側設計
- ComponentHandler内部でSerializedObjectの共通ユーティリティを定義
- Play Mode制限ロジックとPrefab保存ロジックを整理
- Undo/EditorUtility.SetDirty/PrefabUtility.RecordPrefabInstancePropertyModificationsの使い分け
-
Node側設計
- ハンドラの入力検証、フィールドパス正規化(
[x]→.Array.data[x])
- dry-run/実行共通処理
- 失敗時の例外をMCPレスポンスに整形
-
エージェント文脈更新
.claude/ などのエージェント設定に「SerializeField更新ツール」「テストファースト」の方針を追記 (scripts/update-agent-context.shを使用)
Phase 2: タスク計画アプローチ
/speckit.tasks で以下カテゴリを生成:
- Setup: research.md・data-model.md・contracts/・quickstart.mdの作成
- Test (RED): Nodeユニットテスト、Unity EditModeテスト(シーン/Prefab/dry-runケース)
- Core実装: Nodeハンドラ + Unity ComponentHandler拡張 + コマンド登録
- Integration: README更新、テストグリーン確認、ログ出力整備
- Polish: CLIヘルプ・ドキュメント、LLM向けquickstart調整
- 依存関係:
research -> data-model/contracts -> tests (RED) -> 実装 -> テストGREEN -> ドキュメント
- 並列化: Node側テスト/実装とUnity側テスト/実装を[P]でマークし、別担当が並行可能
- すべてのタスクに「テストが先」のチェックボックスを付与し、コミット時にテスト結果を記録
この計画により、要件化→Research→設計→TDD実装の流れを明文化し、/speckit.tasks 実行および以降の実装フェーズに進む準備が整った。
Tasks
タスク: SerializeField 値更新ツール
入力: /specs/SPEC-0b6b106c/ の設計ドキュメント
前提条件: plan.md (完了), research.md/data-model.md/contracts/quickstart.md (これから作成)
実行フロー (main)
1. plan.md を開き技術スタックと対象パスを確認
2. research.md / data-model.md / contracts/ / quickstart.md を順次作成
3. Setup → Tests(RED) → 実装 → Integration → Polish の順序でタスクを実行
4. テストが失敗した状態 (RED) を確認してから実装に進む
5. すべてのタスクで TDD / 小刻みコミット / ログ更新を徹底
Phase 3.1: セットアップ / ドキュメント
Phase 3.2: テストファースト (RED)
Phase 3.3: コア実装 (GREEN化)
Phase 3.4: 統合・ドキュメント
Phase 3.5: 仕上げ / リリース準備
依存関係
- T001→T002-T004 (仕様が無いと設計不可)
- T006/T007/T008 (RED) が T009〜T013 (実装) より先
- T009完了後でなければ T014 (GREEN確認) に進まない
- T011完了後にのみ T012〜T015 実行可
- ドキュメント更新 (T017, T020) は実装/テストを依存
並列実行例
# ドキュメント整備後
並列1: [P] T002 data-model.md 作成
並列2: [P] T003 contracts JSON Schema
並列3: [P] T004 quickstart 手順
# 実装フェーズ
並列1: Node側 T009
並列2: Unity側 T011 (ただし共通仕様に従い連携)
注意事項
- すべての [P] タスクは異なるファイルを対象とし依存関係が無い場合のみ並列実行する
- コミットは RED→GREEN→リファクタ単位で細かく行い、各コミットに対応するテスト結果を記載
set_component_field は高リスク操作のため dry-run サポートを常に確認 (T007/T017)
TDD
TODO
Research
Research: SerializeField 値更新ツール
1. SerializedPropertyパス表記
- 決定: MCP入力では人が読みやすい
foo.bar[0].baz を受け取り、Unity側では .Array.data[n] を含む正規化パスを使用する。
- 理由: LLMや人間にとって
[n] 記法が直感的であり、Unityの SerializedProperty APIのみが .Array.data[n] を要求するため。
- 検討した代替案: 入力段階から
.Array.data[n] を強制 → 可読性が下がり、ユーザーエラーが増えるため却下。
2. Prefab保存フロー
- 決定: Prefab資産を直接編集した場合は
PrefabUtility.SaveAsPrefabAsset を実行し、Prefab Stageやシーン上のインスタンスには PrefabUtility.RecordPrefabInstancePropertyModifications を適用する。
- 理由: SaveAsPrefabAssetはアセット書き込みを保証し、Stage/シーンでは記録のみで十分。
- 検討した代替案: すべてApplyPrefabInstanceで統一 → シーンインスタンスに不要なApplyが走り履歴が汚れるため却下。
3. Play Mode制約
- 決定: Play Mode中は
runtime:true が明示されていない限り、SerializeField更新を拒否し、構造変更 (親子変更/レイヤー) は常に禁止する。
- 理由: Runtime用の変更は一時的であり、Undo/ドメインリロードに依存する。意図確認が必須。
- 検討した代替案: Play Modeでも常に許可 → 予期せぬゲーム状態破壊リスク大。
4. dry-run出力
- 決定: dry-runは
dryRun: true, previewValue, previousValue, resolvedPath, notes[] を返し、実オブジェクトを変更しない。
- 理由: 安全性のため preview を提供し、後続の本適用とレスポンス形式を揃えられる。
- 検討した代替案: dry-run専用レスポンスにする → クライアント実装が複雑になるため却下。
5. 参照型の指定方法
- 決定:
objectReference.assetPath または objectReference.guid を受け取り、なければ value に直接パスを受け付ける。GUID優先で解決に失敗した場合は詳細なエラーを返す。
- 理由: GUID経由が最も安定しており、既存のアセット参照ワークフローとも整合する。
- 検討した代替案: InstanceIDを直接受け取る → セッションを跨ぐと無効になる。
6. ログポリシー
- 決定:
set_component_field カテゴリで JSON構造ログ (target, scope, dryRun, result/ error) を出力し、Undo登録状況も記録する。
- 理由: 監査性とトラブルシュート性を確保し、遠隔操作を追跡可能にするため。
- 検討した代替案: 既存ログに文字列連結で追記 → 解析しづらく目的を達成できない。
Data Model
Data Model: SerializeField 値更新ツール
ComponentFieldUpdateRequest
| フィールド |
型 |
必須 |
説明 |
| scope |
enum(auto,scene,prefabStage,prefabAsset) |
任意 (default auto) |
操作対象の明示スコープ。autoはパスに応じて自動判定。 |
| gameObjectPath |
string |
scopeがscene/prefabStage/autoでPrefabAsset未指定時は必須 |
先頭/付きヒエラルリーパス。Prefab Stageでも同形式。 |
| prefabAssetPath |
string |
scope=prefabAsset または Prefab資産編集時 |
Assets/... .prefab のパス。 |
| prefabObjectPath |
string |
任意 |
Prefab資産内で操作する相対パス (省略時はPrefab root)。 |
| componentType |
string |
必須 |
MonoBehaviour/コンポーネントの短名または完全修飾名。 |
| componentIndex |
int >=0 |
任意 (default 0) |
同一タイプ複数存在時のインデックス。 |
| fieldPath |
string |
必須 |
SerializeFieldパス。foo.bar[0].baz 形式で受け付ける。 |
| serializedPropertyPath |
string |
任意 |
既に正規化された .Array.data[n] パスを指定する場合に使用。 |
| value |
any |
dryRun=false の場合必須 |
設定したい値 (JSONオブジェクト/配列/スカラー)。 |
| valueType |
enum |
任意 |
auto/bool/int/float/string/enum/objectReference/json ... 入力ヒント。 |
| enumValue |
string |
任意 |
enumを識別する文字列 (valueが数値のときに補助)。 |
| objectReference |
object |
任意 |
assetPath/guid を含む参照指定。 |
| runtime |
bool |
任意 (default false) |
Play Modeで実行する際に true 指定。 |
| dryRun |
bool |
任意 (default false) |
trueの場合は検証のみを実施。 |
| applyPrefabChanges |
bool |
任意 (default true for prefabAsset) |
Prefab資産編集時に保存するか。 |
| createUndo |
bool |
任意 (default true) |
シーン/Prefab StageでUndo履歴を残すか。 |
| markSceneDirty |
bool |
任意 (default true) |
シーンへの変更をDirty扱いにするか。 |
検証ルール
gameObjectPath と prefabAssetPath は少なくとも一方が必要。
- scope=
prefabAsset の場合 prefabAssetPath 必須 / gameObjectPath 任意。
value が省略されるのは dryRun=true または valueType='null' の場合のみ。
objectReference 指定時は assetPath か guid のどちらかが必須。
ComponentFieldUpdateResult
| フィールド |
型 |
説明 |
| scope |
enum |
実際に処理したスコープ (scene,prefabStage,prefabAsset). |
| gameObjectPath |
string |
処理対象GameObjectの絶対パス。Prefab資産の場合はPrefab内のパス。 |
| prefabAssetPath |
string? |
Prefab資産編集時に設定。 |
| serializedPropertyPath |
string |
Unity互換の正規化パス。 |
| previousValue |
any |
変更前の値 (dryRun時も含む)。 |
| appliedValue |
any |
適用後の値。dryRun時は preview 値。 |
| requiresSave |
bool |
追加でPrefab保存/シーン保存が必要か。 |
| dryRun |
bool |
dry-run実行かどうか。 |
| notes |
string[] |
Prefab Stage警告やPlay Mode制約などの追加情報。 |
| error |
string? |
失敗時のみ設定。 |
Related Entities
- TargetObjectContext:
isPrefabStage, isSceneObject, isPrefabAsset, scenePath, prefabRoot, playMode。
- ValidationError:
code, message, details。NodeハンドラはこれをMCPエラーとして返す。
Quickstart
Quickstart: SerializeField 値更新ツール
-
ターゲットを特定する
unity-cli raw get_hierarchy で GameObjectパスを取得。
unity-cli raw list_components または get_component_values でコンポーネント名とフィールドを確認。
- Prefab資産を編集する場合は
Assets/.../Foo.prefab のフルパスを控える。
-
dry-runで検証する
{
"gameObjectPath": "/LevelRoot/EnemySpawner",
"componentType": "EnemySpawner",
"fieldPath": "_spawnInterval",
"value": 2.0,
"valueType": "float",
"dryRun": true
}
- レスポンスの
dryRun: true と previewValue を確認し、notes に保存要否/Play Mode警告が出ていないかを読む。
-
本適用を行う
- 同じPayloadで
dryRun を false にして再送信。
- Prefab資産を編集する際は以下を追加:
{
"prefabAssetPath": "Assets/Prefabs/Enemy.prefab",
"prefabObjectPath": "/EnemyBoss",
"applyPrefabChanges": true
}
- 結果の
requiresSave が true の場合は Unity Editor で該当シーン/Prefabを保存。
-
Play Mode中の扱い
- Play Modeで値を触る場合は
"runtime": true を追加し、構造変更は禁止。
runtime を付けないままPlay Modeで送信すると、ツールは安全のためエラーを返す。
-
参照型フィールド
- 参照を差し替える場合は
objectReference ブロックを利用:
{
"objectReference": {
"guid": "0123456789abcdef0123456789abcdef"
},
"valueType": "objectReference"
}
-
エラー時のトラブルシュート
notes にフィールド未発見/型不一致の理由が記載される。
- それでも解決しない場合は
unity-cli raw get_component_values でフィールド名を再確認。
-
監査ログ
- すべての更新は
set_component_field カテゴリで構造化ログが残る。dry-runも記録されるため、セッション後に差分を追跡できる。
Contracts
Migrated from local files. See artifact comments below.
Checklists
Artifact files under checklists/ are managed in issue comments with checklist:<name> entries.
Acceptance Checklist
Spec
機能仕様書: SerializeField 値更新ツール
機能ID:
SPEC-0b6b106c作成日: 2025-11-07
ステータス: 下書き
入力: ユーザー説明: "Scene/prefab SerializeField update tooling"
ユーザーシナリオ&テスト (必須)
ユーザーストーリー1 - シーン内SerializeFieldを正確に更新したい (優先度: P1)
レベルデザイナーがMCPクライアントからシーン内のGameObjectを指定し、非公開のSerializeField値を正確に変更したい。値変更はUndoや再実行ができ、ヒエラルキーの位置を壊さずに安全に適用される必要がある。
この優先度の理由: LLMオペレーションの主目的がシーン調整であり、人手介入を省略できると制作時間を大幅に削減できるため。
独立テスト: 任意のシーンGameObjectに対して単一フィールド更新を指示し、レスポンスが旧値と新値を返しつつ、実際のUnityシーンで値が置き換わることを確認すれば完了。
受け入れシナリオ:
ユーザーストーリー2 - Prefab資産をバッチ調整したい (優先度: P2)
テクニカルアーティストがPrefab資産を複数まとめて調整する際、Unityを手動で開かずにMCPからSerializeField値を変更したい。変更後はPrefab保存状態が明示され、必要に応じて差分をプレビューしたい。
この優先度の理由: Prefab調整は繰り返し作業であり、遠隔更新により作業時間とエラーを削減できるため。
独立テスト: 任意のPrefab資産に対して更新コマンドを発行し、レスポンスに保存状況と必要な後処理(保存済/保存待ち)が含まれるかを検証する。
受け入れシナリオ:
ユーザーストーリー3 - 変更前検証だけを実行したい (優先度: P3)
QAオペレーターが安全性のために「適用せず検証のみ」を実行し、ターゲット解決が正しいかを確かめたい。dry-run結果により、影響範囲が安全であると判断できる。
この優先度の理由: 誤更新によるPrefab破損を避けられ、規模の大きいチームで承認フローを組みやすいため。
独立テスト: dry-runフラグを立ててコマンドを実行し、Unity上の値が変わらずレスポンスだけにプレビュー値が含まれることを確認する。
受け入れシナリオ:
エッジケース
要件 (必須)
機能要件
主要エンティティ
スコープ外 (オプション)
技術制約 (該当する場合)
前提条件 (該当する場合)
依存関係 (該当する場合)
get_hierarchy、list_components、get_component_valuesなどのツールから得られるパス・フィールド情報。成功基準 (必須)
Plan
実装計画: SerializeField 値更新ツール
機能ID:
SPEC-0b6b106c| 日付: 2025-11-07 | 仕様: spec.md入力:
/specs/SPEC-0b6b106c/spec.mdの機能仕様実行フロー (/speckit.plan コマンドのスコープ)
概要
シーン/Prefabに紐づくSerializeFieldをリモートから安全に更新できるMCPツールを追加する。ユーザーはGameObjectパスまたはPrefab資産パスを指定して単一フィールドを更新し、dry-run・旧値/新値・保存要否・エラー理由を受け取る。Play Mode中の制約、Prefab Stage、オブジェクト参照、配列/enumなどの特例を標準化し、Undo/ログポリシーを含めて自動操作の安全性を確保する。
技術コンテキスト
言語/バージョン: Node.js 18.x (ESM) / C# 9 + Unity 2021LTS〜2023LTS
主要依存関係: MCP SDK, better-sqlite3 (既存), UnityEditor API (SerializedObject/PrefabUtility)
ストレージ: 既存のMCP設定/ログ+Unity项目ファイル (追加永続化なし)
テスト: Node.js
node --test、Unity Editor Test Runner (EditMode)対象プラットフォーム: デスクトップOS上のUnity Editor + Node CLI
プロジェクトタイプ: multi (unity-cli + Unityパッケージ)
パフォーマンス目標: 単一フィールド更新を1秒以内に完了、dry-runは500ms以内で応答
制約: Play Modeではruntime:true指定時のみ許可、Prefab編集時は保存手順を必ず提示
スケール/スコープ: 10^3 GameObjects / 10^2 Prefab資産の運用を想定
憲章チェック
シンプルさ:
ComponentFieldUpdateRequestとSerializeFieldResultの2つに統一予定 ✅アーキテクチャ:
テスト (妥協不可):
可観測性:
set_component_fieldカテゴリーを追加し、対象パス/結果/エラーを構造化出力 ✅バージョニング:
package.jsonのpatchアップデート記録を追加 ✅プロジェクト構造
ドキュメント
ソースコード
Phase 0: アウトライン&リサーチ
未確定事項
Array.data[x]等)リサーチタスク (research.mdに記録)
リサーチ成果の書式
Phase 1: 設計&契約
data-model.md
ComponentFieldUpdateRequestscope,gameObjectPath,prefabAssetPath,componentType,fieldPath,valueType,value,enumValue,objectReference,dryRun,applyPrefabChanges,createUndo,markSceneDirtyComponentFieldUpdateResultscope,gameObjectPath,prefabAssetPath,serializedPropertyPath,previousValue,appliedValue,requiresSave,notes[],dryRuncontracts/
set_component_field.request.json/set_component_field.response.json(JSON Schema) を追加quickstart.md
Unity側設計
Node側設計
[x]→.Array.data[x])エージェント文脈更新
.claude/などのエージェント設定に「SerializeField更新ツール」「テストファースト」の方針を追記 (scripts/update-agent-context.shを使用)Phase 2: タスク計画アプローチ
/speckit.tasksで以下カテゴリを生成:research -> data-model/contracts -> tests (RED) -> 実装 -> テストGREEN -> ドキュメントこの計画により、要件化→Research→設計→TDD実装の流れを明文化し、/speckit.tasks 実行および以降の実装フェーズに進む準備が整った。
Tasks
タスク: SerializeField 値更新ツール
入力:
/specs/SPEC-0b6b106c/の設計ドキュメント前提条件: plan.md (完了), research.md/data-model.md/contracts/quickstart.md (これから作成)
実行フロー (main)
Phase 3.1: セットアップ / ドキュメント
/specs/SPEC-0b6b106c/research.mdに SerializedPropertyパス表記・Prefab保存方針・PlayMode制約の調査結果を記載/specs/SPEC-0b6b106c/data-model.mdでComponentFieldUpdateRequestとComponentFieldUpdateResultの属性・検証ルールを定義/specs/SPEC-0b6b106c/contracts/set_component_field.request.jsonと.response.jsonを作成し、MCP↔Unity間Payload契約を記述/specs/SPEC-0b6b106c/quickstart.mdに LLM利用者向けのドライラン→本適用→保存確認の手順を書く.claude/settings経由のscripts/update-agent-context.sh claudeを実行し、新ツールの利用方針/TDD必須をエージェント文脈に追記Phase 3.2: テストファースト (RED)
unity-cli/tests/unit/handlers/component/ComponentFieldSetToolHandler.test.jsに入力バリデーション・dry-run・Prefab適用・エラー分岐を網羅するREDテストを追加UnityCliBridge/Packages/unity-cli-bridge/Tests/Editor/Handlers/ComponentHandlerTests.csにシーン/Prefab/dry-run/PlayModeブロックのEditModeテスト (失敗状態) を追加tests/test-mcp-component-tools.mdにset_component_field用のチェック項目 (U30-04) を追加し、差分比較ステップを記述Phase 3.3: コア実装 (GREEN化)
unity-cli/src/handlers/component/ComponentFieldSetToolHandler.jsを実装し、フィールドパス正規化・value型推論・dry-run処理を追加unity-cli/src/handlers/index.jsとREADME.mdにツール登録と説明を追記UnityCliBridge/Packages/unity-cli-bridge/Editor/Handlers/ComponentHandler.csに SerializedProperty更新ロジック/Prefab保存/PlayModeガードを実装 (tests T007 をGREEN化)UnityCliBridge/Packages/unity-cli-bridge/Editor/Core/UnityCliBridge.csにset_component_fieldルーティングを追加し、ログを出力UnityCliBridge/Packages/unity-cli-bridge/Editor/Handlers/ComponentHandler.csへ構造化ログ/Undo/notes収集を追加Phase 3.4: 統合・ドキュメント
unity-cli/tests/unit/handlers/component/ComponentFieldSetToolHandler.test.jsをGREENにし、npm run test:unit -- tests/unit/handlers/component/ComponentFieldSetToolHandler.test.jsを記録Unity -runTests -testPlatform editmode ...で実行し、Prefab/シーンテスト結果を共有tests/test-mcp-component-tools.mdのU30-04シナリオを実走し、Before/Afterスナップショット手順を更新specs/SPEC-0b6b106c/quickstart.mdとREADME.mdに dry-run→適用→保存のワークフローを反映Phase 3.5: 仕上げ / リリース準備
unity-cli/src/core/config.js周辺でset_component_fieldのログ/メトリクスカテゴリを登録し、loggerテストを追加unity-cli/package.jsonと Unityパッケージpackage.jsonにバージョン・エクスポート項目を更新 (必要なら)CHANGELOG.md/README.ja.md/CLAUDE.mdに新フロー・注意事項を追記 (TDD必須を再強調)docs/manual-tests/component-field-set.md(新規) に残す依存関係
並列実行例
注意事項
set_component_fieldは高リスク操作のため dry-run サポートを常に確認 (T007/T017)TDD
TODO
Research
Research: SerializeField 値更新ツール
1. SerializedPropertyパス表記
foo.bar[0].bazを受け取り、Unity側では.Array.data[n]を含む正規化パスを使用する。[n]記法が直感的であり、UnityのSerializedPropertyAPIのみが.Array.data[n]を要求するため。.Array.data[n]を強制 → 可読性が下がり、ユーザーエラーが増えるため却下。2. Prefab保存フロー
PrefabUtility.SaveAsPrefabAssetを実行し、Prefab Stageやシーン上のインスタンスにはPrefabUtility.RecordPrefabInstancePropertyModificationsを適用する。3. Play Mode制約
runtime:trueが明示されていない限り、SerializeField更新を拒否し、構造変更 (親子変更/レイヤー) は常に禁止する。4. dry-run出力
dryRun: true,previewValue,previousValue,resolvedPath,notes[]を返し、実オブジェクトを変更しない。5. 参照型の指定方法
objectReference.assetPathまたはobjectReference.guidを受け取り、なければvalueに直接パスを受け付ける。GUID優先で解決に失敗した場合は詳細なエラーを返す。6. ログポリシー
set_component_fieldカテゴリで JSON構造ログ (target, scope, dryRun, result/ error) を出力し、Undo登録状況も記録する。Data Model
Data Model: SerializeField 値更新ツール
ComponentFieldUpdateRequest
auto,scene,prefabStage,prefabAsset)/付きヒエラルリーパス。Prefab Stageでも同形式。Assets/... .prefabのパス。foo.bar[0].baz形式で受け付ける。.Array.data[n]パスを指定する場合に使用。auto/bool/int/float/string/enum/objectReference/json... 入力ヒント。assetPath/guidを含む参照指定。検証ルール
gameObjectPathとprefabAssetPathは少なくとも一方が必要。prefabAssetの場合prefabAssetPath必須 /gameObjectPath任意。valueが省略されるのはdryRun=trueまたはvalueType='null'の場合のみ。objectReference指定時はassetPathかguidのどちらかが必須。ComponentFieldUpdateResult
scene,prefabStage,prefabAsset).Related Entities
isPrefabStage,isSceneObject,isPrefabAsset,scenePath,prefabRoot,playMode。code,message,details。NodeハンドラはこれをMCPエラーとして返す。Quickstart
Quickstart: SerializeField 値更新ツール
ターゲットを特定する
unity-cli raw get_hierarchyで GameObjectパスを取得。unity-cli raw list_componentsまたはget_component_valuesでコンポーネント名とフィールドを確認。Assets/.../Foo.prefabのフルパスを控える。dry-runで検証する
{ "gameObjectPath": "/LevelRoot/EnemySpawner", "componentType": "EnemySpawner", "fieldPath": "_spawnInterval", "value": 2.0, "valueType": "float", "dryRun": true }dryRun: trueとpreviewValueを確認し、notesに保存要否/Play Mode警告が出ていないかを読む。本適用を行う
dryRunをfalseにして再送信。{ "prefabAssetPath": "Assets/Prefabs/Enemy.prefab", "prefabObjectPath": "/EnemyBoss", "applyPrefabChanges": true }requiresSaveがtrueの場合は Unity Editor で該当シーン/Prefabを保存。Play Mode中の扱い
"runtime": trueを追加し、構造変更は禁止。runtimeを付けないままPlay Modeで送信すると、ツールは安全のためエラーを返す。参照型フィールド
objectReferenceブロックを利用:{ "objectReference": { "guid": "0123456789abcdef0123456789abcdef" }, "valueType": "objectReference" }エラー時のトラブルシュート
notesにフィールド未発見/型不一致の理由が記載される。unity-cli raw get_component_valuesでフィールド名を再確認。監査ログ
set_component_fieldカテゴリで構造化ログが残る。dry-runも記録されるため、セッション後に差分を追跡できる。Contracts
Migrated from local files. See artifact comments below.
Checklists
Artifact files under
checklists/are managed in issue comments withchecklist:<name>entries.Acceptance Checklist