build-gtk について
Unity Editor 開発者向けに、Graph Toolkit の公開 API を使ったグラフやステートマシンの編集ツール作成を支援するスキルです。バージョン確認、構造設計、検証、ランタイムアセットへのインポートを扱います。
主な機能
- 01公開 API によるグラフツール作成
- 02ステートマシン編集ツールの作成
- 03ノード、ポート、オプションの設定
- 04グラフの検証と問題の報告
- 05ScriptedImporter によるアセット変換
活用シーン
- 01Unity プロジェクト用のグラフエディター作成
- 02状態と遷移を持つステートマシンの構築
- 03編集データのランタイムアセットへの取り込み
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ unity-technologies/ skills --skill build-gtkインストール後、Claude Code で/build-gtkを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/graph-api.mdpitfalls.mdruntime-and-visualization.mdstate-machine-api.md詳細
Unity Graph Toolkit (GTK)
Unity の Graph Toolkit モジュールを使い、Unity.GraphToolkit.Editor 名前空間の公開 API のみで、エディターグラフツールとステートマシンツールを作成します。
重要
- 変更に問題があった場合に戻せるよう、復元ポイントを作成してください。
- 指示されたことだけを行ってください。無関係なアセットやファイルは変更しないでください。長い説明は避けてください。
- ワークフローや診断を進める前に、そのワークフローで指定されている参照ファイルと、実施しようとしている内容を扱うトピックマップのページを開いて読みます。回答では、読んだファイル名を挙げてください。Unity に関する学習知識は古かったり、誤っていたり、異なる Unity バージョンのものだったりする可能性があり、Graph Toolkit は 6000.4、6000.6、6000.7 の間で変更されているためです。
参照資料
必要に応じて以下をお読みください。パスはこのスキルのフォルダーからの相対パスです。
references/graph-api.md— Graph API の範囲:Graph、Node、ポートおよびオプションのビルダー、コンテキストノードとブロックノード、サブグラフ、変数、検証、ツールバー、コンテキストメニュー。グラフツールのコードを書く前にお読みください。references/state-machine-api.md— State Machine API(Unity 6.7 以降):StateMachine、State、Condition、トランジションとルール、自己遷移、カスタムビュー。ステート、トランジション、条件に関わる作業の際にお読みください。references/runtime-and-visualization.md— ScriptedImporter を使ってグラフまたはステートマシンをランタイムアセットにコンパイルする方法、およびグラフエディターで実行状況をリアルタイム表示する方法。ユーザーが作成したデータをゲーム内で使うことや、ランタイムでデバッグすることを希望している場合にお読みください。references/pitfalls.md— コンパイルは通っても残る問題。引き渡し前、およびユーザーからコンパイルエラー、空の Add メニュー、ノードの欠落、例外について報告があった場合にお読みください。
手順 1:エディターのバージョンを確認し、API を選択する
コードを書く前に、ProjectSettings/ProjectVersion.txt の m_EditorVersion を読みます。Graph Toolkit はエディターモジュールであり、インストールするパッケージはありません。com.unity.graphtoolkit は非推奨の互換用シムなので、マニフェストに追加してはいけません。
| エディターバージョン | 利用できる機能 |
|---|---|
| 6000.4 より前 | 廃止された実験的パッケージ(0.x)のみ利用可能です。その API はこのスキルとは異なります。アップグレードを推奨してください。 |
| 6000.4~6000.5 | モジュールはありますが、ポート容量、型キャスト、ワイヤーとノードの可視化、USS によるノードのスタイル設定、要素 ID はありません。 |
| 6000.6 | このスキルで説明する Graph API を利用できます。 |
| 6000.7 以降 | 上記すべてに加え、State Machine API、NodeView<T> / StateView<T> / ConditionView<T> カスタム UI、[GraphMenu] / [BlackboardMenu] コンテキストメニュー、変更差分 GraphLogger.GraphChanges、ポートの型追従、Blackboard の型制限を利用できます。参照資料では、該当するメンバーに 6.7 の印が付いています。 |
6000.7 より前のエディターでステートマシンツールを求められた場合は、State Machine API を利用できないことを明確に伝えてください。求められない限り、Graph API で代用しないでください。
メンタルモデル
-
Graph Toolkit はオーサリング用のフレームワークです。グラフを描画して永続化しますが、実行することはありません。 ユーザーがランタイムのデータモデルと実行コードを記述し、通常は ScriptedImporter からそれらにデータを渡します。
-
GraphまたはStateMachineのサブクラスごとにアセットタイプが 1 つあり、[Graph("ext")]または[StateMachine("ext")]に渡すファイル拡張子で識別されます。 -
検出にはリフレクションを使用します。グラフクラスと同じアセンブリ内のノード、ステート、条件クラスは自動的に一覧表示されます。 ほかのアセンブリにあるクラスは、
[UseWithGraph]または[UseWithStateMachine]を指定すると登録されます。抽象クラスは一覧表示されません。 -
すべてのオーサリングクラスには
[Serializable]を指定し、Editorフォルダー、または Editor プラットフォームに制限された asmdef のいずれかに配置します。 -
ユーザー向けにコンパイルされるのはパブリック API のみです。左列の名前が下書きに含まれている場合は、作業を止めて右列を使用してください。
使用しない 代わりに使用する GraphModel、GraphObject、GraphTool、Stencil、BaseGraphToolGraphとGraphDatabaseNodeModel、PortModel、WireModelNode、IPort、WireStateModel、TransitionModel、ConditionModelState、ITransition、Condition<T>GraphViewEditorWindow、GraphElementsExtensionMethodsCache、ModelViewウィンドウは提供済みです。カスタム UI には 6000.7 で NodeView<T>を使用しますUnityEditor.Experimental.GraphView、graphViewChanged、Port.Create相当するものはありません。ツールは GraphクラスとNodeクラスとしてモデル化しますマニフェスト内の com.unity.graphtoolkit不要です。このモジュールは組み込みです
ワークフロー A:グラフツールを構築する
コードを書く前に、今すぐ references/graph-api.md を読んでください。メンバー名とビルダーチェーンは記憶に頼らず、ここを参照してください。手順 5 に該当する場合は、references/runtime-and-visualization.md も読んでください。
-
グラフクラス。
[Graph(AssetExtension)] [Serializable] class MyGraph : Graphを定義し、public const string AssetExtensionを追加します。[MenuItem("Assets/Create/...")]を指定した静的メソッドを追加し、GraphDatabase.PromptInProjectBrowserToCreateNewAsset<MyGraph>()を呼び出します。サブグラフが必要な場合は、属性にGraphOptions.SupportsSubgraphsを渡します。 -
ノードクラス。
[Serializable] class MyNode : Nodeを定義します。OnDefinePortsをオーバーライドし、すべてのポートのビルダーチェーンの最後に.Build()を指定します。インスペクターで編集可能な設定にはOnDefineOptionsをオーバーライドします。ポートが設定に依存する場合は、OnDefinePorts内でGetNodeOptionByName(name).TryGetValue<T>(out var v)を使って設定を読み取ります。数のように入力を重ねて変更するオプションには.Delayed()を指定し、キー入力のたびにポートが再構築されないようにします。配置、アイコン、デフォルトのタイトル、USS の指定には[Node("Category/Path", iconPath, title, stylesheet)]を使用します。 -
検証。
OnGraphChanged(GraphLogger logger)をオーバーライドし、logger.LogError、LogWarning、またはLogで報告します。問題のあるノードまたはポートをコンテキストとして渡し、その箇所にマーカーが表示されるようにします。このコールバック内でグラフを変更してはいけません。修正処理は、メッセージに関連付けたGraphLogAction、メニュー項目、またはインポーターに実装してください。 -
必要に応じて構造を追加します。 コンテキストノードとブロックノード、サブグラフ、ブラックボード変数、
IsConnectionAllowedによる型変換、ツールバー要素、またはコンテキストメニューを追加できます。詳細はgraph-api.mdを参照してください。 -
出力。 同じ拡張子に登録した
ScriptedImporterによって、グラフを通常のランタイムアセットにコンパイルします。形式は常に次のとおりです。var graph = GraphDatabase.LoadGraphForImporter<MyGraph>(ctx.assetPath); // never LoadGraph here if (graph == null) return; // bad path or type: log and stop var start = graph.GetNodes().OfType<StartNode>().FirstOrDefault(); if (start == null) return; // OnGraphChanged already reported it var next = start.GetOutputPortByName("Next").FirstConnectedPort?.GetNode(); // null when unconnected var titlePort = next.GetInputPortByName("Title"); titlePort.TryGetValue<string>(out var title); // the value typed on the node if (titlePort.IsConnected) { /* resolve titlePort.FirstConnectedPort.GetNode() upstream instead */ } ctx.AddObjectToAsset("Runtime", runtime); ctx.SetMainObject(runtime);ランタイムアセットとそのアセンブリから
Unity.GraphToolkit.Editorを参照してはいけません。また、Hash128ID はHash128のまま維持してください。デバッグビューとコードで構築するグラフについては、runtime-and-visualization.mdを参照してください。 -
確認は以下の説明に従って行います。
ワークフロー B:ステートマシンツールを構築する(Unity 6.7 以降)
references/state-machine-api.md を今すぐ読んでください。この API にはまだ手動の手順ガイドがないため、メンバー名について正確な情報源はこのファイルと Script Reference のみです。
- ステートマシンクラス。
[StateMachine(AssetExtension)] [Serializable] class MySM : StateMachineを定義し、StateMachineDatabase.PromptInProjectBrowserToCreateNewAsset<MySM>()を呼び出すメニュー項目を追加します。 - ステート。
[Serializable] class Patrol : Stateのように定義します。ステートにはポートがありません。トランジションはステートマシンが所有します。OnDefineOptionsで宣言したオプションは、Graph Inspector にのみ表示されます。 - 条件。
[Serializable] [Condition("Health")] class HealthCondition : Condition<float>のように定義します。比較演算子が必要な場合は、protected override bool DisplayComparisonDropdown => trueを設定します。値を持たないトリガーには、Conditionを直接継承します。グループ(And/Or)条件と変数条件は組み込みで用意されているため、再実装しないでください。 - 任意。 カスタムの自己トランジション(
SelfTransitionと[Transition(...)])、StateView<T>およびConditionView<T>によるカスタム UI、[StateMachineMenu]/[ConditionMenu]の項目を追加できます。 - 検証。
OnStateMachineChanged(StateMachineLogger logger)をオーバーライドします。ルールはOnGraphChangedと同じです。 - 出力。
ScriptedImporterでStateMachineDatabase.LoadStateMachineForImporter<MySM>を使用して読み込み、GetStates()、各ステートのGetOutgoingTransitions()、各トランジションのGetRules()、各ルールのRootConditionツリーを順に処理します。このツリーには組み込みの種類とユーザー定義クラスの両方が常に含まれるため、コンパイラーはカスタムのCondition<T>型と照合する前に、IGroupCondition(再帰処理し、Operationを尊重)とIVariableCondition(Variable.Name、Comparison、Value)を処理する必要があります。
コードからグラフを編集する
メニュー項目、ジェネレーター、またはツールでアセットを構築または編集する場合は、変更処理を次のように囲みます。
LoadGraph/CreateGraph → UndoBeginRecordGraph("Action") → AddNode、Connect、
port.TrySetValue、CreateVariable → GraphDatabase.SaveGraph(graph) → UndoEndRecordGraph()。
ステートマシンの場合は、UndoBeginRecordStateMachine、Connect(fromState, toState)、
SaveStateMachine、UndoEndRecordStateMachine が対応する処理です。OnEnable、OnDisable、
OnGraphChanged、または OnStateMachineChanged 内で変更すると、InvalidOperationException がスローされます。
判断事項
| ユーザーの要望 | 対応方法 | 理由 |
|---|---|---|
| ポートが受け入れるワイヤーの数を制限する | ポートビルダーで .WithCapacity(PortCapacity.Single)(または Multi、None)を指定します | ポートはデフォルトで複数のワイヤーを受け入れるため、宣言した場合にのみフレームワークが上限を適用します |
int 出力を float 入力に接続する | Graph.IsConnectionAllowed(IPort output, IPort input) をオーバーライドします | 異なる型のポートはデフォルトでは接続できません。グラフが記録するのはワイヤーだけで、インポーターが変換します |
| Shader Graph のように、複数の型を受け入れるポート | 6000.7 以降:ビルダーで .WithDataTypes(typeof(float), typeof(int), typeof(Vector3)) を指定します。6000.6:型指定のないポートと IsConnectionAllowed を使います | WithDataTypes は 6000.6 にはありません |
| データ型のない実行フローポート | 型を指定せずに context.AddInputPort("In") を使います。DataType は Untyped になります。フロー向けの見た目にするには .WithConnectorUI(PortConnectorUI.Arrowhead) を追加します | フローポートは値を運ばないため、型を指定すると誤った接続を招きます |
| Add メニューからノード型を非表示にする | abstract にするか、[UseWithGraph] を付けずに別のアセンブリに移動するか、GraphOptions.DisableAutoInclusionOfNodesFromGraphAssembly を設定してノードを明示的に追加します | グラフのアセンブリ内にある具象ノードクラスは、すべて自動的に一覧表示されます |
| Add メニューでノードをグループ化する | [Node("Category/Sub")] を指定します。クラス名またはタイトル名がパスの後に追加されます | 属性の最初の引数はフォルダーパスであり、ノードのタイトルではありません |
以前の graphViewChanged のように、変更内容を把握する | 6000.7 以降:OnGraphChanged と ChangeKinds フラグを使い、追加・変更されたノードを logger.GraphChanges.ChangedNodes で確認します。削除されたノード(どのバージョンでも)と、6000.6 でのすべての変更を把握するには、キャッシュしたノード ID の HashSet<Hash128> と GetNodes() の差分を取ります | GraphChanges は 6000.7 で追加され、削除されたノードは報告せず、削除されたポートのみを報告します |
| 複数種類のサブグラフ | メイングラフに GraphOptions.SupportsSubgraphs を指定し、各サブグラフの Graph クラスに [Subgraph(typeof(MainGraph))] を指定します | この属性がない場合、メイングラフ型が唯一のサブグラフ型も兼ねます |
| サブグラフノード上のポート | サブグラフ内に VariableKind.Input または Output の種類の Blackboard 変数を作成します | サブグラフノードには OnDefinePorts がなく、そのポートはサブグラフの変数を反映します |
| ノードアイコンまたは USS の見た目 | [Node(category, iconPath, title, stylesheet)] を指定します。ダークテーマ用のアイコンファイルには d_ プレフィックスを付けます | エディターはダークテーマでは d_ のファイルを選び、それ以外では通常のファイルにフォールバックします |
| 実行時にどのノードが実行され、ポートを通じて何が流れるかを表示する | GraphVisualization API を使います。詳しくは runtime-and-visualization.md を参照してください | Graph Toolkit にはランタイムがありません。ゲーム側から開いているウィンドウに状態を送り返す必要があります |
| Animator のようなステートマシンエディター | 6000.7 以降ではワークフロー B を使います。6000.6 では利用できないことを説明します | State Machine API は 6000.7 より前にはありません |
| ノード内に追加の UI を表示する | 6000.7 以降では NodeView<MyNode> を使います。6000.6 では USS、DefaultColor、FillAmount のみを使えます | NodeView<T> は 6000.7 で追加されました |
制約
- メンバー名は参照資料に記載されているとおりに正確に使用してください。プロパティは PascalCase(
FirstConnectedPort、IsConnected)で、属性には位置引数を渡し、ID にはHash128を使用します。参照資料に記載されていないメンバーは、名前や大文字・小文字を推測せず、以下の URL パターンで調べてください。推測したメンバー名ではコンパイルに失敗し、ユーザーには誤記なのか機能がないのか判断できません。 - ドキュメントが更新されても回答が正確であるよう、内容を繰り返し説明するのではなく、スクリプトリファレンスまたはマニュアルへのリンクを掲載してください。
- ランタイムアセンブリから
Unity.GraphToolkit.Editorを除外し、ビジュアライゼーションコードは#if UNITY_EDITOR内のランタイムアセンブリに配置してください。このモジュールは Editor 専用であり、参照するとプレイヤービルドが失敗します。 - ユーザーの既存のツール構成を維持し、言及されていないノードのスタイル変更や再編成はしないでください。ノード名とポート名は、インポーターや保存済みアセットが依存する検索キーです。
- 回避策として Graph Toolkit の内部実装やプライベート型を使用しないでください。これらはユーザーコードからアクセスできず、予告なく変更されます。公開 API で実現できない場合は、その旨を伝え、以下のコミュニティスレッド一覧を案内してください。
検証
references/pitfalls.mdを読み、ユーザーに提示する前にコードを確認してください。- プロジェクトがエラーなしでコンパイルできることを確認してください。Unity CLI が利用できる場合は、それを使ってビルドするか、Editor をヘッドレスで実行してください。利用できない場合は、ユーザーに Editor をフォーカスして Console の内容を報告するよう依頼してください。
- 新しいメニュー項目からアセットを作成し、ダブルクリックして開きます。Add メニューからすべてのノード型または状態型を追加し、接続して保存した後、閉じて開き直してください。Console にエラーや警告が表示されないことを確認してください。
- インポーターを使用する場合は、アセットを選択し、生成されたランタイムオブジェクトが Inspector でメインアセットとして表示されることを確認してください。
3b. ランタイムコード(エグゼキューターやデバッグビューなど)を記述した場合は、状態に入ったことやノードが実行されたことを示す
Debug.Log行を追加し、Play モードにしてログを確認してください。動作を確認したら、ログ行を削除するか、実行されないようにしてください。 references/pitfalls.mdを再度読み、指摘された問題を修正してください。- 手順に失敗した場合、または Console にエラーが報告された場合は、その手順の参照ファイルと トピックマップ ページを読み直してから再試行してください。見落としていたメンバー名やバージョン条件が原因であることがよくあります。
最終報告
作成または変更したファイルとその配置場所、最初のアセットの作成方法と開き方、インポーターが生成するもの、コードの対象となる Editor のバージョンを、短いチェックリストにしてユーザーに伝えてください。追加するノード型、ランタイムエグゼキューター、デバッグビューなど、ユーザーが次に決めることや行うこと、および Editor を利用できず確認できなかった Console エラーがあれば、それも記載してください。
トピックマップ
WebSearch よりも WebFetch を優先してください。こちらのほうが高速で、目的のページを直接取得できます。必要なものだけを取得してください。
取得する前に <VERSION> を置き換えてください。
docs.unity.com/en-us/engine/<VERSION>とdocs.unity3d.com/<VERSION>/Documentation:ProjectSettings/ProjectVersion.txtに記載されているプロジェクトの Editor バージョンです。例:6000.6または6000.7。docs.unity3d.com/Packages/com.unity.graphtoolkit-samples@<VERSION>:Package Manager に表示されるサンプルパッケージの バージョンです。例:0.6。
以下のページはすべて https://docs.unity.com/en-us/engine/<VERSION>/ 配下にあり、.md
サフィックスを付けたままにすると Markdown として提供されます。
- マニュアルの目次:
manual/extending-the-editor/gtk-index.md - グラフツールの実装:
manual/extending-the-editor/gtk-index/implementing-a-graph-tool.md。子ページとして、このフォルダー内にimplement-a-graph-tool.md、implement-nodes.md、implement-node-options.md、implement-context-nodes.md、implement-block-nodes.md、type-cast-ports.md、add-custom-toolbar-actions.md、add-subgraph-support.md、graph-processing.mdがあります。 - グラフウィンドウとパネル:
manual/extending-the-editor/gtk-index/landing-graph-interface.md。子ページとして、その下にgraph-window.md、blackboard.md、graph-inspector.md、minimap.mdがあります。 - スクリプトリファレンス:
script-reference/unity/graphtoolkit/editor/<type>.mdと.../<type>/<member>.md。すべて小文字で、ジェネリックのアリティは省略されます(Condition<T>の場合はcondition.md)。 例:script-reference/unity/graphtoolkit/editor/graph/ongraphchanged.md。ステートマシンの型は6000.7以降で利用できます。旧形式のhttps://docs.unity3d.com/<VERSION>/Documentation/ScriptReference/Unity.GraphToolkit.Editor.<Type>.htmlも HTML としてアクセスできます。 - サンプル:
https://docs.unity3d.com/Packages/com.unity.graphtoolkit-samples@<VERSION>/manual/index.html。 Package Manager でcom.unity.graphtoolkit-samplesを名前でインストールし、Texture Maker (インポーター)、Visual Novel Director(カスタムランタイムとデバッグビュー)、または Dungeon Graph Generator (コードからグラフを構築)をインポートしてください。 - コミュニティ:https://discussions.unity.com/tag/graph-toolkit