mcpField
U
unity-editor

unity-editor

github.com/besty0728開発1.9k94 回インストール今日更新
リポジトリ

unity-editor について

unity-editor は、Unity Editor の状態確認や操作を行うスキル群です。シーン変更の記録や Play Mode の制御に対応し、シーン YAML の直接解析は不要です。

主な機能

  1. 01シーンとファイルの変更記録を取得
  2. 02エディターのコンテキストと状態を確認
  3. 03Play Mode の制御とフレーム送り
  4. 04GameObject の実行時状態を確認
  5. 05オブジェクト選択、取り消し、やり直し
  6. 06メニュー実行とタグ・レイヤーの取得

活用シーン

  1. 01作業再開時に Unity の永続的な変更を確認
  2. 02シーンを実行してオブジェクトのコンポーネント状態を確認
  3. 03Play Mode を1フレームずつ進めて動作を検証
  4. 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 が処理を再開したときは、.unity YAML を読む前に editor_get_changes を呼び出してください
  • editor_get_changes.dropped=true の場合 → 500 件の保持上限を超えています。scene_context / scene_diff でコンテキストを再構築してください

スキルの概要

スキル説明
editor_playPlay Mode に入る
editor_play_captureランタイムエラーを確認し、必要に応じてスクリーンショットを撮影してから終了する
editor_stopPlay Mode を終了する
editor_pause一時停止を切り替える
editor_playmode_stepPlay Mode を N フレーム進める(非同期ジョブ)
editor_playmode_inspectGameObject の実行中のランタイム状態(transform、コンポーネントのフィールド)を調べる
editor_run_scenarioinvoke / read / assert / wait の各ステップを、1 つの非同期検証ジョブとして実行する(「ランタイム検証シナリオ」を参照)
editor_selectGameObject を選択する
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 を示すエラーが返されます。

パラメーター型必須デフォルト説明
framesintいいえ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 で確認してください。

パラメーター型必須説明
namestringいいえ*オブジェクト名
instanceIdintいいえ*インスタンス ID(優先)
pathstringいいえ*オブジェクトパス
componentTypestringいいえコンポーネントの型名。指定すると、そのパブリックフィールド/プロパティも返されます

*識別子を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 を選択します。

パラメーター型必須説明
namestringいいえ*オブジェクト名
instanceIdintいいえ*インスタンス ID(優先)
pathstringいいえ*オブジェクトパス

*識別子を1つ指定してください

editor_get_selection

現在選択されているオブジェクトを取得します。

戻り値: {count, objects: [{name, instanceId}]}

editor_get_context

選択項目、アセット、シーン情報を含むエディターのコンテキスト全体を取得します。

ParameterTypeRequiredDefaultDescription
includeComponentsboolNofalseコンポーネントの一覧を含めます
includeChildrenboolNofalse子オブジェクトの情報を含めます

戻り値:

  • 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 を解析または返すことはありません。

ParameterTypeRequiredDefaultDescription
sincelongNo0前回の応答カーソル。0 を指定すると保持されている履歴を読み取ります
typesstringNoallscene、file、undo、lifecycle をカンマ区切りで指定します
sourcestringNoalleditor/manual、rest、または all
limitintNo100返す最新のエントリ数。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

メニューコマンドを実行します。

ParameterTypeRequiredDescription
menuPathstringYesメニュー項目のパス

一般的なメニューパス:

Menu PathAction
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"])

ベストプラクティス

  1. 再生モードの操作前にエディターの状態を確認してください
  2. 再生モード中にシーンを変更しないでください(変更は失われます)
  3. 安全に試行するには、元に戻す機能を使用してください
  4. 再開時は、シーンファイルを読み取る前に editor_get_changes を呼び出してください
  5. 一括操作用の instanceId を取得するには、editor_get_context を使用してください
  6. メニューコマンドは正確なパスと一致させる必要があります

正確なシグネチャ

正確な名前、パラメーター、デフォルト値、戻り値は、このファイルではなく、GET /skills/schema または unity_skills.get_skill_schema() で定義されています。

よくあるエラー

トランスポートレベルのエラーコード全般(COMPILING/RATE_LIMIT など)→ ../../references/protocol-error-codes.md

ErrorTriggerFix
TARGET_NOT_FOUND要求された GameObject またはメニュー項目が見つかりませんでした(例:Menu item not found or failed)。再試行する前に、gameobject_find/scene_get_hierarchy でオブジェクトを確認するか、メニューパスの正確な表記を確認してください。
SKILL_ERRORAlready 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 分に制限します。

コメント