Unity Skillsシステムでワークフローを自動化する:SKILL.md完全ガイド

Unity AI完全マスターシリーズ
第1回 — Unity AI Assistant入門:Ask・Plan・Agentモード完全解説
第2回 — Unity MCP完全ガイド:Claude Code・Codex・Gemini・CursorをUnity Editorに接続する
第3回 — Unity MCPカスタムツールの作り方:McpTool Deep Diveと4つの登録方式
第4回 — Unity SkillsシステムでAIワークフローを自動化する:SKILL.md完全ガイド (この記事)
Appendix — Unity MCPビルトインツール完全リファレンス:51個のツールパラメータ・有効化ガイド
第5回 — Unity AI AssistantのProject Overview自動生成:AIがプロジェクトを理解するようにする方法
第6回 — Unity AI Assistant × Profiler:性能ボトルネックを自然言語で診断する実践ガイド

AI Assistantに同じパターンの作業を繰り返し頼んでいると、説明がどんどん長くなっていきます。たとえば「レベルに敵スポナーを配置して」というシンプルな依頼ひとつでも — 「空のGameObjectを作成し、EnemySpawnerコンポーネントを追加し、敵プレハブのリストをScriptableObjectから読み込んで接続し、NavMesh上に配置されているか確認し、Gizmoがシーンビューに表示されているかまでチェックして」と毎回ひとつひとつ手順を書き出さないと、AIはどこかの工程を飛ばしてしまいます。次の会話で同じ作業を頼むときも、同じ指示を最初から書き直すことになります。

Skillsシステムは、この繰り返しをなくすために設計されました。ワークフローの指示・使用するツール・必要なパッケージ条件を1つのSKILL.mdファイル(大文字小文字を区別)にパッケージングしておくと、AssistantがEditorを開くたびに自動的に発見し、必要な瞬間に取り出して使います。一度作成すれば.unitypackageでチーム全体と共有することもできます。

先ほどの敵スポナーのワークフローを例に挙げてみます。Assets/AI/Skills/place-enemy-spawner/SKILL.mdとして5つの手順を一度定義しておけば — それ以降は「ここに敵スポナーを追加して」という一言で済みます。Assistantがdescriptionフィールドを読み取って自動的にこのSkillをアクティブ化し、内部に記載された5ステップを順番に実行します。EnemySpawnerコンポーネントを忘れたり、NavMeshの検証を飛ばしたりすることがなくなります。新しいメンバーが加わっても同じ一言で同じ結果が得られるため、ワークフローが人によってブレることもありません。

この記事はUnity 6.3(com.unity.ai.assistant 2.7)基準で、Skillsシステムの構造と実践的な活用方法をまとめます。

TL;DR
SkillsSKILL.mdファイル(大文字小文字を区別)で定義する、再利用可能なAIワークフローモジュール
自動発見Assets/またはユーザースキルフォルダに配置するとEditor起動時に自動スキャン
Progressive Disclosure:初期ロードはYAMLメタデータのみ → 詳細ファイルは必要時のみロード
Static Utility Functionpublic static C#メソッドを登録なしでスキルから呼び出し可能
チーム共有.unitypackageでエクスポートすればインポート直後から自動発見

目次


Skillsとは何か

Skillsは、特定のワークフローに関する指示とメタデータをパッケージ化してUnity AI Assistantを拡張する、モジュール型の機能です。単純にプロンプトを保存しておくものとは異なります。スキルファイルの中には、「どんな状況でこのスキルを使うべきか」「どんな手順をどの順番で実行すべきか」「プロジェクトのどのC#メソッドを呼び出すべきか」といった、AIが従うべき指示やガイドラインが詰まった、いわば”作業手順書”です。

公式ドキュメントが示すSkillsの核心的な特性は4つです。

Skillsの核心的な特性4つ Progressive Disclosure 初期はメタデータのみロード 詳細は必要時のみロード 自然言語ワークフロー 固定文法なし 口語的な指示も動作 ビルトインアクション 標準サポート シーンクエリ・スクリーンショット・ C#実行を宣言不要で利用可能 複数スキルの組み合わせ 1つの会話で 複数スキルを同時に使用 公式推奨手順:Assistantチャットでワークフローを直接試す → 動作確認 → SKILL.mdに記録 スキルはワークフローがスキルなしで既に安定して動作する場合のみ作成する — スキルなしで3〜4回実行、スキルありで3〜4回実行、結果を比較して改善が測定できた場合のみ作成

実践的なヒントを一つ。公式ドキュメントは、スキルファイルを先に作ってテストするのではなく、Assistantのチャットでワークフローを直接試して動作を確認してからSKILL.mdに書き起こす方法を推奨しています。既に動作が検証済みの指示をファイルとして固めるため、はるかに安定した結果が得られます。

重要な点が一つあります。Unity AI AssistantのSkillsは、Unity Agent(Ask・Plan・Agentモード)でのみロードされます。 実際に検証した結果、AI Gatewayを経由して利用するClaude CodeやCodexなどの外部エージェントは、それぞれ独自のハーネス内で動作するため、UnityのSKILL.mdを読み込みません。Claude CodeであればCLAUDE.mdやClaude Code専用のSkillsを、CodexであればAGENTS.mdを別途用意する必要があります。エージェントごとに専用の指示ファイルが必要になるということです。


ファイルの配置場所

Assistantが自動でスキャンする場所は2箇所です。

種類 パス スコープ
プロジェクトスキル Assets/ディレクトリ内のどこでも そのプロジェクト内のみで使用
ユーザースキル Windows:%APPDATA%\Unity\AIAssistantSkills
macOS:~/Library/Application Support/Unity/AIAssistantSkills
同じマシン上の複数プロジェクトで共有

プロジェクトスキルはGitでチームと直接共有でき、ユーザースキルは個人の作業スタイルを複数のプロジェクトに一括適用するときに便利です。ユーザースキルフォルダがまだ存在しない場合は、Edit > Project Settings > AI > Skills > Create user skills folderボタンで作成できます。

スキャンのタイミングはEditor起動時とドメインリロード時です。スキルを追加・修正した場合は新しいAssistantの会話を開始する必要があります。既存の会話には変更が反映されません。


SKILL.mdファイル構造

YAMLフロントマター

スキルフォルダの推奨構成は以下の通りです。

Assets/MySkills/
└─ my-test-skill/
   ├── SKILL.md
   ├── references/
   │   ├── api-notes.md
   │   └── common-patterns.md
   └── resources/
       ├── scenario_A.md
       └── template.cs

YAMLフロントマターの全体構造は以下の通りです。

---
name: my-test-skill
description: Just a test skill. Activate it if we want to test skills.
required_packages:
  com.unity.inputsystem: ">=1.8.0"
  com.unity.cinemachine: ">=3.0.0, <4.0.0"
required_editor_version: ">=6000.3.13"
enabled: true
tools:
  - MyTools.Log
---

各フィールドの役割をまとめます。

フィールド 必須 説明
name 必須 スキルの一意な名前。フォルダ名と合わせるのが慣例
description 必須 スキルの内容とアクティベートすべき状況。AIがアクティベートの判断に使用
required_packages 任意 指定したパッケージがインストールされている場合のみスキルをアクティベート
required_editor_version 任意 スキルのアクティベート条件となるUnity Editorのバージョン範囲
enabled 任意 falseに設定すると無効化。デフォルトはtrue
tools 任意 スキルのアクティベート中にAssistantが使用できるカスタムツールIDのリスト

descriptionフィールドが実質的に最も重要です。AIはこの説明を読んで、現在のユーザープロンプトに対してどのスキルをアクティベートするかを判断します。「このスキルをいつ使えばよいか」を明確に記述するほど、自動アクティベートの精度が高まります。また、>=<などの演算子を含むバージョン文字列は、YAMLのパースエラーを避けるために必ず引用符で囲む必要があります。

本文:自然言語による指示の書き方

SKILL.mdの本文は固定文法のない自然言語の指示です。口語体の指示文もそのまま機能します。公式ドキュメントの例に登場する表現を見ると、その感覚がつかめます。

  • "アセット作成を呼び出す前に、必ず対象オブジェクトを確認します。" — 順序の強制
  • "ステップ3(検証)は絶対にスキップしません。" — 絶対禁止条件
  • "正確に1つのパスのみに従います。異なるパスのステップを混在させません。" — 分岐処理ルール
  • "スクリーンショットを撮って、ハットが対象オブジェクトの上に正確に配置されたことを視覚的に確認します。" — 検証指示

単純な手順の列挙を超えて、「特定の条件でどのパスを進むか」という分岐ロジック、「必ず通らなければならない検証ステップ」、「絶対にやってはいけないこと」といった制約条件も自然言語で表現できます。SKILL.mdの目標サイズはできる限り500行以内に収め、詳細な内容はサポートファイルに委ねるのが理想です。

サポートファイルの構成

resources/references/は慣例的な名前です。別の名前を使っても構いませんが、SKILL.mdの指示から正確な相対パスで参照する必要があります。スキルがアクティベートされた時点で必要なファイルのみがロードされるため、初期コンテキストのサイズには影響しません。

よく使われるパターンは3つです。

  • コードテンプレート"'resources/snippet.cs'テンプレートを使用してMonoBehaviourを作成します。"
  • APIリファレンス"使用可能なメソッドとパラメータは'references/my-api.md'を参照します。"
  • ステップごとの詳細手順"配置手順の全体は'resources/placement-steps.md'に従います。"

Progressive Disclosure — コンテキストを節約する戦略

プロジェクト内のスキルが5個、10個と増えていく場面を想像してみてください。すべてのSKILL.mdの内容が会話開始時にコンテキストウィンドウへまるごと読み込まれると、AIが利用できるコンテキスト領域はあっという間に枯渇します。Skillsシステムはこの問題をProgressive Disclosure(段階的開示)戦略で解決します。エージェントAIを積極的に活用している開発者の方には見覚えのある戦略かもしれません。

初期ロードフェーズでは、YAMLフロントマター(namedescriptionなどのメタデータ)のみがコンテキストウィンドウに読み込まれます。スキルが10個あっても、初期にロードされるのは各スキルのメタデータだけです。スキルがアクティベートされた瞬間に、本文の指示と必要なサポートファイルがその時点で読み込まれます。

Editor起動 / ドメインリロード 全SKILL.mdをスキャン name + description メタデータのみロード (スキル数に関係なく軽量) ユーザー プロンプト スキルアクティベート判断 descriptionを比較 → 関連スキルを選択 ThoughtsセクションでActivate Skillを確認可能 スキル実行 本文の指示をロード resources/ references/ 必要時のみロード (コンテキストは必要時のみ消費)

この構造のおかげで、スキルが増えても平常時のコンテキスト消費は最小限に抑えられます。サポートファイル(resources/references/)は、スキルが実際に実行されるときだけロードされます。


Static Utility Function

AgentToolとの違い

[AgentTool]属性とStatic Utility Functionは、どちらもAssistantがC#メソッドを活用できるようにしますが、呼び出しメカニズムが異なります。

項目 [AgentTool] Static Utility Function
登録 属性が必要 不要
呼び出し方式 AIが直接呼び出す スキルが生成したC#コードで呼び出す
パラメータの渡し方 AIが判断して渡す スキルの指示に明示された通りに渡す
適したケース 高レベルの再利用可能な動作 プロジェクト固有の精密な制御が必要な動作

[AgentTool]はAIが自由に判断して呼び出すのに対し、Static Utility Functionはスキルの指示が「いつ、どのパラメータで呼び出すか」を明示します。属性の登録なしにpublic staticメソッドをそのまま使えるため、既存のエディタユーティリティクラスをスキルで直接再利用できるというメリットもあります。

ユーティリティクラスの設計原則

スキルの指示は完全なメソッド名(Namespace.ClassName.MethodName)でC#コードを生成して呼び出します。公式ドキュメントが示すユーティリティクラスの設計原則は以下の通りです。

要素 目的
完全なクラスパス スキルの指示からメソッドを特定できるようにする(例:Acme.Editor.HatUtils.PlaceHatOnTarget()
明確なパラメータ名と型 AIが正しい値でメソッド呼び出しを構成できるようにする
名前付きフィールドを持つ戻り値の構造体 AIが値を名前で読み取り、次のステップへ連携できるようにする
Successフィールド AIが成功・失敗を一貫して判断できるようにする
Messageフィールド 結果やエラーの説明を提供する

戻り値の型をstringbool1つに単純化してしまうと、AIが次のステップで必要な値を取り出しにくくなります。名前付きフィールドを持つ構造体(またはクラス)で返すのがポイントです。

public static PlaceHatOutput PlaceHatOnTarget(int hatAssetInstanceId, int targetInstanceId, float yOffset = -0.1f)
{
    var prefab = EditorUtility.EntityIdToObject(hatAssetInstanceId) as GameObject;
    if (prefab == null)
        return new PlaceHatOutput { Message = $"No prefab found for instance ID {hatAssetInstanceId}." };

    var target = EditorUtility.EntityIdToObject(targetInstanceId) as GameObject;
    if (target == null)
        return new PlaceHatOutput { Message = $"No GameObject found for instance ID {targetInstanceId}." };

    // 位置指定とインスタンス化 ...
    return new PlaceHatOutput {
        Success = true,
        Message = $"Hat placed on '{target.name}'.",
        GameObjectInstanceId = hat.GetInstanceID(),    // 次のステップへ渡す
        PrefabPath = AssetDatabase.GetAssetPath(prefab)
    };
}

[Serializable]
public class PlaceHatOutput
{
    public bool Success;
    public string Message;
    public int GameObjectInstanceId;
    public string PrefabPath;
}

シーンオブジェクトを変更するメソッドでは、Undoサポートも必ず組み込みましょう。既存オブジェクトを変更する際はUndo.RecordObject()を、新しいコンポーネントを追加する際はUndo.AddComponent<>()を使うことで、ユーザーがCtrl+Zで操作を取り消せます。

Instance IDによるUnityオブジェクト参照

Static Utility FunctionはGameObjectComponentUnityEngine.Objectパラメータを直接受け取れません。代わりに、各オブジェクトにメモリ上で割り当てられた整数値であるinstance IDint)を使用します。

命名規則 識別対象
int gameObjectInstanceId シーン内の特定のGameObject
int componentInstanceId GameObjectの特定のComponent
int assetInstanceId プレハブ・テクスチャなどのプロジェクトアセット
int? 上記と同様 オプションのオブジェクトID
int[] gameObjectInstanceIds バッチ処理用の複数オブジェクト

命名規則を守ることで、AIがコンテキストからオブジェクトを正しく識別できます。たとえばhatInstanceIdtargetInstanceIdのように意味のあるプレフィックスを付けると、マルチステップのワークフローでAIがどのIDをどのメソッドに渡すべきか迷うことがなくなります。


実践例:レッドトップハットスキル

Unity公式ドキュメントが提供する完全な例です。AIで3Dのハットを生成し、シーン内の指定オブジェクトの上に配置して、スクリーンショットで結果を検証するワークフローを1つのスキルにパッケージ化しています。

この例がSkillsシステムの理解に適しているのは、単純な手順の列挙にとどまらず、分岐ロジック・必須条件・検証ステップまでを自然言語で表現した実践的なパターンを示しているからです。

YAMLフロントマター

---
name: create-red-tophat
description: AI生成で赤いトップハット3Dアセットを作成し、対象オブジェクトの上に配置します。ハットのXZバウンドを
  対象に合わせ、頂点に位置させます。ユーザーがトップハット生成、キャラクターへの帽子被せ、
  オブジェクトのデコレートを要求した際に使用します。
---

本文の指示構造(重要部分の抜粋):

このスキルで使用するC# API全体は`resources/hatutils-api-reference.md`を参照します。

## 必須ルール

- アセット作成を呼び出す前に、必ず対象オブジェクトを確認します。
- ステップ3(検証)は絶対にスキップしません。

## 1. 対象オブジェクトの確認

## パスA:選択済みオブジェクトを使用
ユーザーが現在の選択を言及し、オブジェクトが選択されている場合のみ従います。
1. 選択コンテキストから選択済みオブジェクトのinstance IDを確認します。

## パスB:名前でオブジェクトを指定
ユーザーがオブジェクト名を明示した場合のみ従います。
1. `TestProject.Scripts.HatUtils.FindHatPlacements("<名前>")` C#スクリプトを呼び出します。
2. 最初の一致結果を対象として使用し、`GameObjectInstanceId`を記録します。

## パスC:対象が未指定
既存の対象が指定されていない場合のみ従います。
1. `TestProject.Scripts.HatUtils.FindHatPlacements()` C#スクリプトを呼び出します。
2. 結果リストから対象を選択するようユーザーに求めます。

重要:正確に1つのパスのみに従います。異なるパスのステップを混在させません。

## 2. ハットの生成と配置

1. 生成:モデルに「光沢のある赤いトップハットを生成します」と指示します。アセットのinstance IDを記録します。
2. 配置:`TestProject.Scripts.HatUtils.PlaceHatOnTarget(hatAssetInstanceId, targetInstanceId)`を呼び出します。
3. コライダーの調整:`TestProject.Scripts.HatUtils.FitHatCollider(hatInstanceId)`を呼び出します。

## 3. 検証

スクリーンショットを撮って、ハットが対象オブジェクトの上に正確に配置されたことを視覚的に確認します。
配置が正しくない場合は調整後に再検証します。
検証を3回以上繰り返しません — 代わりにユーザーに入力を求めます。

赤いボックスで強調した3行がこのスキルの核心です。ステップ3の検証は必ず実行する、パスは厳密に1つだけ従う、検証を3回以上繰り返さない — これらの制約がAIの自由な解釈を防ぎ、予測可能な動作を担保します。

実際のresources/hatutils-api-reference.mdには、FindHatPlacements()PlaceHatOnTarget()FitHatCollider()各メソッドの完全なシグネチャ、パラメータ表、戻り値の構造体フィールドが含まれます。スキルの本文を軽量に保ち、詳細なAPI情報はサポートファイルに分離するパターンです。


スキルのテスト&検証

ロードの確認Edit > Project Settings > AI > Skillsページを開きます。3つのセクションに分かれています。

セクション 内容
Project skills 現在のプロジェクトのAssets/で発見されたスキルの一覧
User skills ユーザースキルフォルダに保存されたスキルの一覧
Skills with issues detected パースまたは検証の問題があるスキル

スキルが「Issues detected」セクションに入っている場合、原因はほぼ次の3つのいずれかです。空のスキルファイル、nameまたはdescriptionフィールドの欠落、---区切り文字の欠落。Rescanボタンでスキャンを再実行して結果を更新できます。

アクティベートの確認:Assistantの会話ウィンドウのThoughtsセクションでActivate Skillと共にskill_nameパラメータが表示されていれば、スキルが正常にアクティベートされています。アクティベートが表示されない場合は、まずdescriptionフィールドの説明が十分に具体的かどうかを確認してください。

スキルが必要かどうかの判断:公式ドキュメントが推奨する方法です。

  1. 特定のドメインとシナリオを選択する
  2. スキルなしで同じプロンプトを3〜4回実行する
  3. スキルありで同じプロンプトを3〜4回実行する
  4. 結果を比較 — 測定可能な改善がある場合のみスキルを作成する

ワークフローがスキルなしで既に安定して動作するなら、スキルを追加することでかえって不要な複雑さを増やす可能性があります。


チーム共有(.unitypackage)

スキルの作成とテストが完了したら、.unitypackageとしてエクスポートしてチームメンバーや他のプロジェクトと共有できます。Unityの標準アセットパッケージワークフローをそのまま使用します。

パッケージに含めるもの:

  • SKILL.mdを含むスキルフォルダ全体
  • resources/references/以下のサポートファイル
  • Static Utility Functionやカスタムツール([AgentTool])を定義するEditorスクリプト

他のユーザーがパッケージをインポートすると、Assistantが含まれているスキルを自動的に発見します。追加設定は不要で、Editor起動直後からすぐに使用できる状態になります。


まとめ

Skillsシステムは、Unity AI Assistantをチーム規模のワークフローツールへと変える鍵です。繰り返していたコンテキスト説明をSKILL.mdファイルに固定し、Static Utility Functionでプロジェクトデータへ精密にアクセスし、.unitypackageでチーム全体に配布する — この構造は、プロジェクトの規模が大きくなるほどその真価を発揮します。

最後に一つ。スキルから先に設計しようとすると、方向を見失いがちです。公式ドキュメントが推奨するように、Assistantのチャットで直接試して動作を確認してからファイルにまとめる方が、はるかにスムーズに進められます。SKILL.mdは検証済みのワークフローを記録するものであり、設計文書ではありません。


関連記事


← 前の回: 第3回 — Unity MCPカスタムツールの作り方:McpTool Deep Diveと4つの登録方式
→ Appendix: Unity MCPビルトインツール完全リファレンス — 51個のツールパラメータ・有効化ガイド

コメントする