unity-editor について
unity-editor は、Unity Editor の状態確認や操作を行うスキル群です。シーン変更の記録や Play Mode の制御に対応し、シーン YAML の直接解析は不要です。
主な機能
- 01シーンとファイルの変更記録を取得
- 02エディターのコンテキストと状態を確認
- 03Play Mode の制御とフレーム送り
- 04GameObject の実行時状態を確認
- 05オブジェクト選択、取り消し、やり直し
- 06メニュー実行とタグ・レイヤーの取得
活用シーン
- 01作業再開時に Unity の永続的な変更を確認
- 02シーンを実行してオブジェクトのコンポーネント状態を確認
- 03Play Mode を1フレームずつ進めて動作を検証
- 04エディターメニューや現在の選択項目を確認
MCP 対応
README には MCP との関係について記載がありません。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ besty0728/ unity-skills --skill unity-editorインストール後、Claude Code で/unity-editorを入力して読み込まれたか確認します。
詳細
このモジュール内のスキルを呼び出す前に: 名前や説明から推測したパラメーターでスキルを呼び出そうとしている場合は、いったん停止し、まずこのファイルを読むか、
GET /skills/recommend?includeSchema=trueでスキーマを取得してください。recommend/schema からすでにパラメーター定義を得ている場合は、そのまま dryRun に進めます。
トリガー
- 永続化されたシーン/ファイルの変更を読む
- Play Mode を操作する
- ランタイム状態を調べる
- メニュー項目を実行する
- 永続化されたシーン/ファイルの変更の読み取り、Play Mode の操作、ランタイム状態の確認、メニュー項目の実行
Unity Editor スキル
シーン YAML を解析せずに、Unity Editor を観察および操作します。
動作モード
- Approval:このモジュールは Mixed です。
editor_get_changes/editor_get_selection/editor_get_context/editor_get_state/editor_get_tags/editor_get_layers/editor_playmode_inspectはSkillMode.SemiAutoに設定されており、直接実行できます。それ以外のeditor_select/editor_undo/editor_redo/editor_playmode_stepはデフォルトで FullAuto となり、Approval モードでは grant が必要です。 - Auto / Bypass:FullAuto は直接実行します。
- NeverInSemi の高リスクスキルを含むもの:
editor_play/editor_play_capture/editor_stop/editor_pause(MayEnterPlayMode = trueに設定);editor_run_scenario(MayEnterPlayMode = true、MayTriggerReload = true、RiskLevel = "high"に設定);editor_execute_menu(MayTriggerReload = trueに設定 —Assets/Refresh、Assets/Reimport Allなどのメニュー項目はドメインのリロードを引き起こします)。これらは Approval と Auto のどちらでもMODE_FORBIDDENを返し、Bypass または Allowlist に該当する場合のみ呼び出せます。grant フローはこれらには適用されません。試さないでください。
禁止事項(よくある誤り):
editor_runは存在しません → Play Mode に入るにはeditor_playを使用してくださいeditor_compile/editor_recompileは存在しません →debug_force_recompileを使用してくださいeditor_saveは存在しません → menuPath"File/Save"を指定してeditor_execute_menuを使用してくださいeditor_execute_menuには正確なメニューパスが必要です。誤記があると、失敗しても通知されません
ルーティング:
- コンパイルの確認には →
debugモジュールのdebug_check_compilationを使用してください - コンソールのエラーには →
debugモジュールのdebug_get_errorsを使用してください - シーンの保存には →
scene_save(scene モジュール)または menuPath="File/Save" を指定したeditor_execute_menuを使用してください - ファイル監視で変更が報告されたとき、またはユーザーが Unity を編集した後に AI が処理を再開したときは、
.unityYAML を読む前にeditor_get_changesを呼び出してください editor_get_changes.dropped=trueの場合 → 500 件の保持上限を超えています。scene_context/scene_diffでコンテキストを再構築してください
スキルの概要
| スキル | 説明 |
|---|---|
editor_play | Play Mode に入る |
editor_play_capture | ランタイムエラーを確認し、必要に応じてスクリーンショットを撮影してから終了する |
editor_stop | Play Mode を終了する |
editor_pause | 一時停止を切り替える |
editor_playmode_step | Play Mode を N フレーム進める(非同期ジョブ) |
editor_playmode_inspect | GameObject の実行中のランタイム状態(transform、コンポーネントのフィールド)を調べる |
editor_run_scenario | invoke / read / assert / wait の各ステップを、1 つの非同期検証ジョブとして実行する(「ランタイム検証シナリオ」を参照) |
editor_select | GameObject を選択する |
editor_get_selection | 選択中のオブジェクトを取得する |
editor_get_context | エディターの全コンテキスト(選択、アセット、シーン)を取得する |
editor_get_changes | カーソル位置を基準に、永続化されたシーン/ファイルの変更を読み取る |
editor_undo | 直前の操作を元に戻す |
editor_redo | 直前の操作をやり直す |
editor_get_state | エディターの状態を取得する |
editor_execute_menu | メニュー項目を実行する |
editor_get_tags | すべてのタグを取得する |
editor_get_layers | すべてのレイヤーを取得する |
console_set_pause_on_error | エラー発生時に Play Mode を一時停止する(console モジュール) |
スキル
editor_play
Play Mode に入ります。警告:Play Mode 中に加えた未保存のシーン変更は、終了時に失われます。
戻り値:{success, mode, jobId} — mode="playing"、jobId は AsyncJobService から返される値で、呼び出し側は entering_play_mode の完了をポーリングできます。
editor_play_capture
Play Mode に入り、durationSeconds(デフォルトは 10、範囲は 1~300)にわたってエラーを確認し、必要に応じて Game View をキャプチャしてから終了します。結果に healthy、エラーの集計、stoppedEarly、screenshotPath が含まれる Job を返します。
editor_stop
プレイモードを終了します。
戻り値: {success, mode} — mode="stopped"。
editor_pause
一時停止状態を切り替えます。
戻り値: {success, paused} — paused は新しいブール値です。
editor_playmode_step
EditorApplication.Step を使ってプレイモードを frames 分(1~100、デフォルトは1)進めます。ステップ実行の一環として、Unity は自動的に一時停止状態になります。プレイモードがすでに有効になっている必要があります。先に editor_play または editor_play_capture を呼び出してください。そうでない場合は、構造化されたエラー(error + hint + suggestedSkills: ["editor_play", "editor_play_capture"])が返されます。同時に実行中にできるステップジョブは1つだけです。実行中のジョブがある状態で2回目の呼び出しを行うと、アクティブな jobId を示すエラーが返されます。
| パラメーター | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
frames | int | いいえ | 1 | 進めるフレーム数。1~100の範囲に制限されます |
同期処理ではなく、非同期ジョブとして実行されます: EditorApplication.Step() は後続の Editor ティックでのみ反映されるため、このスキルは一度に1回ずつ Step() を呼び出し、Time.frameCount の進行を監視して反映を確認してから次を呼び出します。この確認を行わずに Step() を連続して呼び出しても、確実には動作しません。呼び出し自体はすぐに戻り、{success, status: "accepted", jobId, framesRequested} が返されます。
返された jobId で job_status をポーリングし、status="completed" になるまで確認してください。その時点で details には {framesRequested, framesCompleted, frameCount, isPaused} が含まれます。job_wait は使用しないでください — playmode/play_capture と同様、このジョブの進行は EditorApplication.update のティックに依存します。一方、job_wait のブロッキングループは同じメインスレッドで実行されるため、進行を確認できず、タイムアウトまで何もせずに待つことになります。プレイモードが終了した場合、または Unity が10秒以内にフレームを進められなかった場合、ジョブは failed_exited_play_mode/failed_step_timeout で失敗します。
editor_playmode_inspect
GameObject の実行時の状態(transform(position/rotation/scale)、activeSelf/activeInHierarchy、および componentType が指定されている場合はそのコンポーネントのパブリックフィールドとプロパティ)を調べます。再実装せず、component_get_properties と同じリフレクションヘルパーを再利用します。プレイモード中(一時停止中を含む)に動作し、編集モードでも動作します。編集モードではエディター時点の値が返されます。値がどちらの状態を反映しているかは、応答の isPlaying/isPaused で確認してください。
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
name | string | いいえ* | オブジェクト名 |
instanceId | int | いいえ* | インスタンス ID(優先) |
path | string | いいえ* | オブジェクトパス |
componentType | string | いいえ | コンポーネントの型名。指定すると、そのパブリックフィールド/プロパティも返されます |
*識別子を1つ指定してください
戻り値: {success, gameObject, entityId, instanceId, path, activeSelf, activeInHierarchy, transform: {position, localPosition, rotation, localScale}, isPlaying, isPaused, component}。componentType が省略された場合、component は null です。型が見つからない場合、またはアタッチされていない場合はエラーオブジェクトが返されます。それ以外の場合は {gameObject, component, fullTypeName, properties, fields}(component_get_properties と同じ形式)が返されます。
editor_select
GameObject を選択します。
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
name | string | いいえ* | オブジェクト名 |
instanceId | int | いいえ* | インスタンス ID(優先) |
path | string | いいえ* | オブジェクトパス |
*識別子を1つ指定してください
editor_get_selection
現在選択されているオブジェクトを取得します。
戻り値: {count, objects: [{name, instanceId}]}
editor_get_context
選択項目、アセット、シーン情報を含むエディターのコンテキスト全体を取得します。
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
includeComponents | bool | No | false | コンポーネントの一覧を含めます |
includeChildren | bool | No | false | 子オブジェクトの情報を含めます |
戻り値:
selectedGameObjects: Hierarchy 内のオブジェクト(instanceId、path、tag、layer)selectedAssets: Project ウィンドウ内のアセット(GUID、path、type、isFolder)activeScene: 現在のシーン情報(name、path、isDirty)focusedWindow: フォーカスされているエディターウィンドウの名前isPlaying、isCompiling: エディターの状態
editor_get_changes
Library/UnitySkills/editor_changes.jsonl にある永続的な変更履歴を読み取ります。Domain Reloads をまたいで、シーンオブジェクト/コンポーネント/プロパティの概要と、インポート、削除、移動されたアセットのパスを記録します。生の .unity YAML を解析または返すことはありません。
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
since | long | No | 0 | 前回の応答カーソル。0 を指定すると保持されている履歴を読み取ります |
types | string | No | all | scene、file、undo、lifecycle をカンマ区切りで指定します |
source | string | No | all | editor/manual、rest、または all |
limit | int | No | 100 | 返す最新のエントリ数。1~500 |
戻り値: {hasChanges, cursor, oldestSeq, dropped, truncated, changes}。次回の呼び出しに備えて cursor を保存してください。dropped=true は、500 件の履歴から古い変更があふれたことを意味するため、シーンのコンテキスト全体を再構築してください。
editor_undo
直前の操作を元に戻します。
editor_redo
最後に元に戻した操作をやり直します。
editor_get_state
現在のエディターの状態を取得します。
戻り値: {isPlaying, isPaused, isCompiling, timeSinceStartup, unityVersion, platform}
editor_execute_menu
メニューコマンドを実行します。
| Parameter | Type | Required | Description |
|---|---|---|---|
menuPath | string | Yes | メニュー項目のパス |
一般的なメニューパス:
| Menu Path | Action |
|---|---|
File/Save | 現在のシーンを保存 |
File/Build Settings... | ビルド設定を開く |
Edit/Play | 再生モードを切り替える |
GameObject/Create Empty | 空のオブジェクトを作成 |
Window/General/Console | コンソールを開く |
Assets/Refresh | アセットを更新 |
editor_get_tags
利用可能なすべてのタグを取得します。
戻り値: {tags: [string]}
editor_get_layers
利用可能なすべてのレイヤーを取得します。
戻り値: {layers: [{index, name}]}
エラー時に一時停止
エラー時の一時停止機能はエディターモジュールではなく、コンソールモジュールで提供されます。
console/SKILL.md の console_set_pause_on_error を使用してください。
使用例
import unity_skills
# Check editor state before operations
state = unity_skills.call_skill("editor_get_state")
if state['isCompiling']:
print("Wait for compilation to finish")
# On resume or after file-watch notification, inspect semantic changes first.
changes = unity_skills.call_skill("editor_get_changes", since=last_cursor)
last_cursor = changes["cursor"]
# Get full context (useful for understanding current state)
context = unity_skills.call_skill("editor_get_context", includeComponents=True)
for obj in context['selectedGameObjects']:
print(f"Selected: {obj['name']} (ID: {obj['instanceId']})")
# Select and operate on object
unity_skills.call_skill("editor_select", name="Player")
selection = unity_skills.call_skill("editor_get_selection")
# Safe experimentation with undo
unity_skills.call_skill("gameobject_delete", name="TestObject")
unity_skills.call_skill("editor_undo") # Restore if needed
# Execute menu command
unity_skills.call_skill("editor_execute_menu", menuPath="File/Save")
# Step through Play Mode frame-by-frame and assert state changed
import time
# Enter Play Mode with a generous observation window so there's time left to step
capture = unity_skills.call_skill("editor_play_capture", durationSeconds=30)
while True:
capture_status = unity_skills.call_skill("job_status", jobId=capture["jobId"])
if capture_status["currentStage"] not in ("entering_play_mode", "domain_reload_recovery"):
break # Play Mode has been entered; capture_status["currentStage"] == "observing"
time.sleep(0.2)
before = unity_skills.call_skill("editor_playmode_inspect", name="Player")["transform"]["position"]
step = unity_skills.call_skill("editor_playmode_step", frames=3)
while True:
step_status = unity_skills.call_skill("job_status", jobId=step["jobId"]) # not job_wait, see above
if step_status["status"] in ("completed", "failed"):
break
time.sleep(0.1)
after = unity_skills.call_skill("editor_playmode_inspect", name="Player")["transform"]["position"]
assert after != before, "Player did not move after 3 frames"
print(step_status["details"]["frameCount"], step_status["details"]["isPaused"])
ベストプラクティス
- 再生モードの操作前にエディターの状態を確認してください
- 再生モード中にシーンを変更しないでください(変更は失われます)
- 安全に試行するには、元に戻す機能を使用してください
- 再開時は、シーンファイルを読み取る前に
editor_get_changesを呼び出してください - 一括操作用の instanceId を取得するには、
editor_get_contextを使用してください - メニューコマンドは正確なパスと一致させる必要があります
正確なシグネチャ
正確な名前、パラメーター、デフォルト値、戻り値は、このファイルではなく、GET /skills/schema または unity_skills.get_skill_schema() で定義されています。
よくあるエラー
トランスポートレベルのエラーコード全般(COMPILING/RATE_LIMIT など)→ ../../references/protocol-error-codes.md
| Error | Trigger | Fix |
|---|---|---|
TARGET_NOT_FOUND | 要求された GameObject またはメニュー項目が見つかりませんでした(例:Menu item not found or failed)。 | 再試行する前に、gameobject_find/scene_get_hierarchy でオブジェクトを確認するか、メニューパスの正確な表記を確認してください。 |
SKILL_ERROR | Already in play mode、Not in play mode、またはフレームステップのジョブがすでに実行中など、再生モードの状態が競合しました。 | 先に再生モードに入る/再生モードを終了するか、既存のステップジョブが完了するまで待ち、エディターの状態をスキルの要件に合わせてください。 |
ランタイム検証シナリオ
editor_run_scenario は、steps(JSON 配列の文字列、1~100 件)、executionMode(デフォルトは play、または明示的に edit)、timeoutSeconds(1~600、デフォルトは 60)を受け取ります。永続化された run_scenario ジョブを返します。少なくとも 1 つの assert または wait_condition が必要です。DryRun は、Play Mode に入ったりコードを呼び出したりせずに、構造とステップのスキルメタデータを検証します。実際の各ステップは引き続き、それぞれの権限を適用して SkillRouter を通過します。呼び出しステップが現在受け付けるのは component_invoke_method のみです。その他のライフサイクルを変更するスキルと、ネストされたシナリオは拒否されます。
ステップ形式:
{"kind":"invoke","skill":"component_invoke_method","args":{...}}:一度呼び出し、ジョブの完了を待ちます。呼び出し引数では、シナリオと同じ executionMode を使用します。{"kind":"read","skill":"component_get_properties","args":{...}}:ReadOnly として宣言されたスキルを実行し、その結果を保持します。{"kind":"assert","expected":42,"select":"returnValue","tolerance":0.01}:直前の結果を比較します。または、ReadOnly のskillとargsを指定して、その場で読み取ることもできます。selectはレスポンスデータを基準とする任意の JSONPath です。パスが存在しない場合、expected が null でも失敗します。数値の許容誤差は、一致する配列やオブジェクトに再帰的に適用されます。{"kind":"wait_frames","frames":2}または{"kind":"wait_seconds","seconds":0.5}:Editor をブロックせずに待機します。フレームは実際の Play フレームカウンターを使用し、秒数は実時間を使用します。Play Mode が一時停止中の場合、フレーム待機は進まず、Edit Mode でのフレーム待機はゼロにする必要があります。{"kind":"wait_condition","skill":"component_get_properties","args":{...},"select":"...","expected":true}:一致するか、シナリオの期限が切れるまで、ReadOnly の状態確認を繰り返します。
Edit Mode から開始したシナリオは Play Mode に入り、終了後に抜けます。Play Mode から開始したシナリオは、そのモードを維持します。シナリオは Application.runInBackground を一時的に有効にし、成功、失敗、キャンセルのいずれの場合も元の値に戻します。Play Mode への移行時または終了時にドメインリロードが発生した場合、ライフサイクルのクリーンアップが再開されます。すでにディスパッチされた呼び出しは中断され、再実行されません。任意の呼び出しは高リスクであり、Undo やアトミック性は保証されません。
ジョブが終端状態になるまでポーリングしてください。resultData.passed が true になるのは、アサーションが成功し、ランタイムの Error/Exception/Assert ログがなく、ログが完全にカバーされている場合のみです。steps には actual、expected、tolerance、passed が含まれ、logWindow と compilation には証拠が保持されます。ランタイムエラー、ログカバレッジの不足、保留中のコンパイル、例外、ターゲットの欠落、タイムアウトは、いずれも検証の失敗となります。キャンセルやタイムアウトが発生しても、任意のユーザーコードが停止したとは限りません。シナリオの外でソースを修正し、コンパイルとリロードの完了を待ってから、新しい検証ジョブを明示的に送信してください。失敗した呼び出しを黙って再実行してはいけません。
AI クライアントのコンパイル → シナリオ → 修正 → 再実行という有限ループについては、ランタイム検証と上限付き修正を使用してください。提供されているヘルパーは、呼び出し元が指定する修正コールバックを受け付け、修正を最大 3 回、予算を 30 分に制限します。