Claude Media
Unreal Engine Skills for Claude Codeの3スキルとフックの使い分け

Unreal Engine Skills for Claude Codeの3スキルとフックの使い分け

EpicのUnreal Engine Skills for Claude Codeプラグインは、3つのスキルとSessionStartフックで構成されます。各部品の役割と、toolsetやAgent Skillを足す手順を解説します。

Unreal Engine Skills for Claude Codeは、Epic Gamesが配布するClaude Code用プラグインです。中身は3つのスキル(unreal-mcp・create-toolset・unreal-skill)と、セッション開始時に動く1本のフックだけです。MCPの接続設定そのものは含まれません。

このプラグインの価値は、Unreal Editorを動かす手順と、Unreal側にツールやスキルを足す手順の両方を、Claudeに「作法つき」で持たせる点にあります。接続の手順はUnreal EngineのMCPをClaude Codeで使う設定手順にあり、ここでは部品ごとの役割と、拡張するときの使い分けを扱います。

プラグインの中身は何で、何をしないのか

リポジトリの構成は小さく、.claude-plugin/plugin.json、hooks/、skills/の3か所で全部です。plugin.jsonのバージョンは3.1.1で、ライセンスはMITです。

構成

プラグインを構成する4つの部品

  • unreal-mcp(スキル)

    稼働中のUnreal Editorに対して、アクターやBlueprintを調べたり書き換えたりするときの手順書です。

  • create-toolset(スキル)

    ClaudeがEditorから呼べる新しいツールセットを、C++またはPythonで作る手順書です。

  • unreal-skill(スキル)

    Unreal側に登録する「Agent Skill」を作る手順書です。Claude Code本体のスキルとは別物です。

  • SessionStartフック

    作業ディレクトリがUnrealプロジェクトだと判定し、短い前提メモをセッションに差し込みます。

しないことも決まっています。.mcp.jsonは同梱されず、EditorのコンソールでModelContextProtocol.GenerateClientConfig ClaudeCodeを実行して生成する設計です。ツール本体もこのプラグインにはありません。ツールはAllToolsetsプラグインが提供し、プラグインはそれを使いこなす指示だけを持ちます。

前提として、EditorでModelContextProtocolとAllToolsetsの両プラグインが有効で、MCPサーバーが起動している必要があります。フックがbashスクリプトなので、WindowsではGit BashかWSLが要ります。PowerShellだけの環境ではフックだけが動かず、MCPツールは使えます。

3つのスキルはどう呼び分けられるか

3つのスキルは、frontmatterのdescriptionにトリガー語と除外条件の両方を書く形で、互いに守備範囲を分けています。Claudeは説明文を見て、どれを読み込むかを決めます。

スキル起動する場面除外される場面
unreal-mcp起動する場面レベルへのアクター配置、Blueprintやマテリアルの編集、Live Codingでの再コンパイルなど、稼働中のEditorへの操作除外される場面概念やドキュメントの質問、Unity・Godotなど他エンジン
create-toolset起動する場面「ツールを足す」「MCPで公開する」「新しいtoolsetを作る」といった依頼除外される場面既存ツールの実行、Agent Skillの作成
unreal-skill起動する場面Agent Skillの新規作成・編集・レビュー除外される場面toolsetの作成、.claude/skills/にあるClaude Code側のスキル

unreal-mcpの説明文には、BP_・WBP_・M_・NS_といったアセット接頭辞や.uprojectも判定材料として並びます。「Unrealと書かれていなくても、これらが出たらUnreal文脈として扱う」という指定です。日本語で「ドアのBlueprintを直して」と頼んでも、接頭辞やエディタ用語が手がかりになる設計です。

unreal-mcp: ツール名を暗記させない設計

unreal-mcpスキルの要点は、ツール名を覚えさせずに毎回探させることです。ツール検索が既定で有効なので、MCPサーバーが最初に見せるのはlist_toolsets・describe_toolset・call_toolの3つだけです。BlueprintTools.createのような個別ツールはtools/listに並ばず、call_tool経由で呼びます。

流れは次の3手です。

手順

ツール呼び出しの基本の流れ

  1. 1

    toolsetを探す

    list_toolsetsで登録済みのツールセットを見ます。作りたいものが分かっていれば省けます。

  2. 2

    スキーマを読む

    describe_toolsetで、候補のツールの引数と型を確認します。

  3. 3

    call_toolで実行する

    toolset_name・tool_name・argumentsを渡します。結果は同じターンで返ります。

スキルにはもう1つ、安全側の約束が書かれています。一括変更の前後で保存を促すこと、C++のコンパイル中はツール呼び出しが不安定なのでLiveCodingToolset.CompileLiveCodingの完了を待つこと、結果を必ず読んで成功と明示されない限り止まること、PIE(Play-in-Editor)中はアセット作成の挙動が変わりうること、の4点です。依存する呼び出しは直列にし、独立した作業だけ並列にする、という指示もあります。

project skillsという抜け道

unreal-mcpは、プロジェクトが独自に登録した「Agent Skill」を探す手順も持っています。AgentSkillToolset.ListSkillsで一覧し、関連しそうなものをGetSkillsで読み、そこにある指示を汎用の既定動作より優先します。プロジェクト固有の命名規則やフォルダ構成を、Claude Code側のCLAUDE.mdではなくEditor側に持たせる経路です。ここに書く側の作法がunreal-skillです。

SessionStartフックは何を差し込むのか

フックの設定は1件で、startup|resume|clearのときにbash ${CLAUDE_PLUGIN_ROOT}/hooks/unreal-context.shをタイムアウト5秒で実行します。

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "startup|resume|clear",
        "hooks": [
          {
            "type": "command",
            "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/unreal-context.sh",
            "timeout": 5
          }
        ]
      }
    ]
  }
}

スクリプトは作業ディレクトリから親へたどり、GenerateProjectFiles.bat・GenerateProjectFiles.sh・GenerateProjectFiles.commandか*.uprojectのどれかを見つけた階層をプロジェクトルートとみなします。Source/やContent/の下で起動しても検出できます。Engineディレクトリの有無は目印にしません。エンジンのソースツリーにはEngine/Source/Runtime/Engineというモジュールがあり、取り違えるためです。

ルートが見つかれば、additionalContextとして次のような文脈を足します。

  • このディレクトリはUnreal Engineプロジェクトで、.uprojectの名前はこれである(エンジンのソースツリーならその旨)
  • C++/UObject、Slate、UHTのUnreal流儀を優先する
  • Editor操作にはunreal-mcpスキルを使う
  • .mcp.jsonがルートにあるかどうか。無い場合はGenerateClientConfigで作るよう案内する

見つからなければ何も出力せずに終了します。Unreal以外のリポジトリで有効化したままにしても、文脈は汚れません。デバッグするときは環境変数CLAUDE_UE_HOOK_DEBUGに任意の値を入れると、検出結果が標準エラーに出ます。

フックは接続の成否には関わりません。効果は「Claudeの最初の振る舞いを揃える」ことだけです。フック全般の仕組みはClaude Code hooksガイドにまとまっています。

ツールセットを足すときは何に気をつけるか

create-toolsetが定める設計原則は、清潔(Clean)・完全(Complete)・合成可能(Composable)・重複なし(DRY)の4つです。Unrealの既存APIをそのまま写さず、テクニカルアーティストが実装を読まずに理解できる形にします。setがあればgetも、createがあればdeleteも用意します。

書く前の確認は5段階あります。

  1. 既存のツールで足りないか。Editorが動いていればlist_toolsetsとdescribe_toolsetで調べる
  2. 依頼が実はもっと一般的なパターンではないか
  3. 同じ領域のtoolsetが既にあれば、新設せずそこへ足す
  4. 新しいtoolsetに専用プラグインが要るか
  5. 実装言語(PythonかC++か)

言語はPythonが基本の推奨で、反復が速いのが理由です。Intermediate/PythonStub/unreal.pyを検索して必要なAPIがあるか確かめ、足りなければC++を選びます。どちらの言語にも必要なAPIが無いときは、回避策を作らず、止めて利用者に伝えるよう指示されています。回避策は壊れやすいという理由です。

共通の約束

C++とPythonに共通する規則は、次のとおりです。

  • ツールはすべて静的メソッドにする。インスタンスの状態は持たない
  • 引数と戻り値は実際の型(int32、FVector、構造体など)を使い、JSON文字列への変換は自分でやらない
  • 戻り値はデータを運ぶ。成功は正常終了、失敗は例外の送出で表し、真偽値やエラー文字列を返さない
  • toolsetクラスとツールごとにドキュメントを書く。ただし署名から読み取れる内容は書かない
  • 全ツールにテストを付け、成功経路と、例外を投げる条件ごとのテストを書く

ドキュメントの方針は、LLMが過剰に書きがちだという前提に立っています。「型や名前から推測できるなら削る」「実装の理由は書かず、仕様だけ書く」「単位・範囲・空の結果の意味のような、コードから分からない情報だけ残す」という基準です。

Pythonの最小形

Python版は、@unreal.uclass()を付けたunreal.ToolsetDefinitionの派生クラスに、@toolset_registry.tool_callと@staticmethodを重ねたメソッドを置きます。型注釈は全引数と戻り値で必須です。スキーマ生成が型注釈だけを頼りにするためです。次は公式の例に沿った形で、名前はプレースホルダです。

@unreal.uclass()
class MyToolset(unreal.ToolsetDefinition):
    """Manages MyThings in the current level. Covers querying by name,
    reading their state, and performing operations on them."""
 
    @toolset_registry.tool_call
    @staticmethod
    def find_things(name_pattern: str) -> list[MyThing]:
        """Returns all things whose name matches the given pattern.
 
        Args:
            name_pattern: Substring to match against thing names.
        """
        if not name_pattern:
            raise ValueError("name_pattern must not be empty.")
        ...

登録は自動ではありません。プラグインの初期化コード(__init__.pyやinit_unreal.py)でunreal.ToolsetRegistry.register_toolset_class(MyToolset)を呼びます。C++版はUToolsetDefinitionを継承し、UFUNCTION(meta = (AICallable))を付けた静的メソッドを公開し、モジュールの起動時にUToolsetRegistry::RegisterToolsetClassを呼びます。長時間かかる処理は、UToolCallAsyncResultの派生型を返す非同期ツールにし、成功をSetValue()、失敗をSetError()で伝えます。

テストはEditorを動かしたまま回す

create-toolsetが最優先とするのは、稼働中のEditorにunreal-mcpでつないだままテストを回す方法です。

1. AutomationTestToolset の DiscoverTests を呼ぶ(最初に必須)
2. ListTests でtoolset名に絞り、検出されたか確かめる
3. RunTests にテストのフルパスを渡す
4. GetTestStatus をポーリングし、GetTestResults で詳細を読む

DiscoverTestsを飛ばすと結果が空になる、と書かれています。Pythonのテストを書き換えたあとは、force_rediscover=trueで再検出します。Editorが動いていないときは、ヘッドレスで走らせる方法があります。起動に約30秒かかりますが、CIで使えます。

UnrealEditor-Cmd.exe <Project>.uproject \
  -ExecCmds="Automation RunTests AI.MyToolset;quit" \
  -Unattended -NullRHI

Pythonを書き換えたあとの再読み込みには、Project SettingsのPlugins > PythonでRemote Executionを有効にし、reload_remote.pyにプラグイン名を渡します。新しいUFUNCTIONを追加したときの再起動要否など、運用の落とし穴は接続手順の記事の「よくあるつまずき」にまとまっています。

Agent Skillは「Claude Codeのスキル」とどう違うか

名前が似ているため、最初に混同しやすい部分です。unreal-skillのdescription自身が「Claude Codeのハーネス側スキル(.claude/skills/)とは別物」と断っています。

観点Claude CodeのスキルUnreal側のAgent Skill
置き場所Claude Codeのスキル.claude/skills/やプラグインのskills/Unreal側のAgent SkillPythonクラス、またはContent BrowserのUAsset
読まれ方Claude CodeのスキルClaude Codeが説明文を見て読み込むUnreal側のAgent SkillAgentSkillToolsetのListSkills・GetSkillsをClaudeが呼んで読む
向く内容Claude Codeのスキルリポジトリ全体の作業手順Unreal側のAgent SkillEditorの中で使うプロジェクト固有の知識(命名規則、フォルダ構成、手順)
作る道具Claude Codeのスキルファイルを書くUnreal側のAgent SkillCreateSkill・UpdateSkill(UAsset)またはPythonクラス

Claude Codeのスキルの仕組みはClaude Code側の話です。Unrealプロジェクトでは両方が併存します。リポジトリの作法はClaude Code側、Editorの中のアセット規約はUnreal側、と分けておくと、どちらに書くか迷いません。

Pythonクラスで作るか、UAssetで作るか

unreal-skillは、スキルを置く場所で道を分けます。

  • プラグインに属するスキル: Pythonクラスで書く。プラグインとバージョンを揃えて管理でき、プラグインが読み込まれると自動で登録される
  • プロジェクト固有でコード不要のスキル: UAssetにする。MCPのCreateSkillで、FolderPath(例/Game/Skills/)、AssetName(PascalCase)、Description、Instructionsを持つDetailsを渡す

更新はUpdateSkillで、SkillPathに/Game/Skills/MyWorkflowSkill.MyWorkflowSkill_Cのようなパスを渡します。作る前にListSkillsで既存のスキルを確認し、既にあれば新規に作らずそちらを案内する、という順序です。

Pythonクラスは@agent_skillを付けたunreal.AgentSkillの派生で、docstringがDescription、クラス属性instructionsが本文になります。次も公式の例に沿った形です。

import unreal
 
from toolset_registry.agent_skill import agent_skill
 
_INSTRUCTIONS = (
    'Do X before Y, because Z.\n'
    'Always verify the result after performing the operation.\n'
)
 
@agent_skill
class MySkill(unreal.AgentSkill):
    """Provides guidance on doing X in Unreal Engine.
    Apply this skill whenever the user wants to accomplish X."""
 
    instructions = _INSTRUCTIONS

登録はインポート時に行われるため、skills/サブフォルダを作り、その__init__.pyで各スキルをインポートし、init_unreal.pyからskillsパッケージを読み込ませます。

良いスキルの条件は「ツールで分かることは書かない」

unreal-skillが挙げる原則は6つです。

  • 新規性(Novel): ツールを呼べば分かることは書かない
  • 同僚口調(Collegial): ドキュメントではなく、知識のある同僚への引き継ぎとして書く
  • 柔軟性(Flexible): 概念でも手順でも、伝わる形でよい
  • 耐久性(Durable): プロパティ名やツール名のように変わりやすいものを埋め込まない
  • 中立性(Agnostic): 周辺の仕組みやモデル名に触れない
  • 簡潔性(Parsimonious): 1トークンごとにコンテキストを使う。抜けても困らない文は削る

「ツール名を埋め込まない」は、unreal-mcpの「ツールは毎回探させる」と同じ思想です。ツール名が変わっても、スキルが静かに壊れません。完成後はGetSkillsで自分のスキルを読み戻し、説明文だけで起動すべき場面が分かるか、本文はツールで分からないことを教えているかを見直します。

導入前に確認したいこと

導入は公式マーケットプレイスにあるため、Claude Codeで/plugin install unreal-engine-skills-for-claude-code@claude-plugins-officialを実行します。チームに配るなら、.claude/settings.jsonのenabledPluginsに同じ識別子をtrueで書きます。この手順は接続の記事に載せてあります。配布を組織で絞っている場合は、strictPluginOnlyCustomizationの影響も受けます。

安全面の注意はREADMEに強く書かれています。MCPサーバーに認証層は無く、同じマシンの別プロセスから接続できます。ProgrammaticToolset.execute_tool_scriptはEditor内で任意のPythonを実行し、承認を外すと確認なしに走ります。READMEは、このプラグインを読み込んだ状態で--dangerously-skip-permissionsを使わないことを勧めています。長いMCPセッションの前には保存とコミットを済ませます。

新しいtoolsetやAgent Skillを作る作業は、既存のアセットやコードを書き換える作業と地続きです。create-toolsetが求める「テストは必須」は、Claudeに任せる作業ほど守る価値があります。

まとめ

導入するだけなら、必要なのはマーケットプレイスの1コマンドと、Editor側のMCP設定です。3つのスキルは、Editorを操作するunreal-mcp、ツールを増やすcreate-toolset、プロジェクトの知識を持たせるunreal-skillと、役割が重ならないように分かれています。

チームで使うなら、最初の拡張はtoolsetではなくAgent Skillがよさそうです。コードを書かず、UAssetとして/Game/Skills/に置けるうえ、プロジェクトの命名規則のような「ツールでは分からない知識」を載せられるからです。toolsetは、既存のツールで届かない操作が見つかってから足せば足ります。

この記事を共有:XはてブLinkedIn