scenario-unreal-gameplay について
Unreal Engine のゲームプレイ開発向けスキルです。データの配置、C++ と Blueprint の分担、GAS、AI、入力、UI を扱い、機能の個別テストと明示的な品質ゲートを重視します。
主な機能
- 01ライフタイムとネットワーク状態に沿ったデータ配置
- 02C++ と Blueprint の役割設計
- 03GAS、入力、AI のワークフロー設定
- 04StateTree、UI、ゲームプレイロジックの検査
- 05デバッグと自動テストによる機能検証
活用シーン
- 01マルチプレイヤーの複製状態と ASC 初期化の計画
- 02キャラクター能力、入力マッピング、AI StateTree の構築
- 03ジャンプ、ダッシュ、クールダウン、体力 UI のテスト
- 04ゲームプレイ実装と性能測定のレビュー
MCP 対応
README では Blueprint グラフの処理方法の一つとして Epic の MCP ツールセットを挙げていますが、このスキル自体が MCP サーバーであるとは説明していません。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-unreal-gameplayインストール後、Claude Code で/scenario-unreal-gameplayを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/critique.mdexpert-notes.mdgui-paths.mdprocedures.mdsources.mdscripts/ue_gameplay_cpp.pyue_gameplay.py詳細
Unreal のゲームプレイ(フレームワーク、Blueprint と C++、入力、GAS、AI、UI)
エキスパートレベルでは、すべてのデータを、そのライフタイムとネットワーク上の存在がデータに一致するクラスに置きます。ロジックは、データのみの Blueprint と、Python で設定するデータアセットの下に、テキスト(C++ または小さな関数)として記述します。また、あらゆるメカニクスを、プレイ中に評価する前に、単独で検証します(注入した入力、デバッグコマンド、トレース)。エージェントは、アクセスできないグラフを作成できるふりはしません。各要素をどのサーフェスに配置するのかを明示し、残った部分だけをエスカレーションします。ここに記載された関連スキルが利用可能なスキルにない場合は、ユーザーにインストールを依頼してください
(npx skills add scenario-labs/skills --skill <name>)。無人で処理を続ける場合は、ツールのスキーマに基づいて進め、不足している点を明示してください。
必須の背景知識: scenario-unreal-expert(チャンネル、レビューループ、5.8 の落とし穴)。
ステータス(2026-09-24): Unreal はインストールされていません。オフラインレイヤーのテストには合格しました
(python3 tests/code/unreal-gameplay/run_all.py --offline)。エディター内のスニペットと生成された C++ ファイルは、いずれもまだ Unreal で実行されていません(C++ はまだコンパイルされていません)。job_00_gameplay_probe.py が [verify] の名前に対応します。
スタンス(専門家の知見)
- データはライフタイムとネットワーク上の存在場所に応じて配置します。 GameMode はサーバー専用のルール、GameState と PlayerState は全員にレプリケートされ、PlayerController は所有者のみに送信されます。Pawn はリスポーン可能な本体であり、GameInstance サブシステムはマップをまたいで存続します(Forsythe IaU2Hue-ApI [00:13:26])。状態は RepNotify を使うレプリケート対象プロパティに保存し、マルチキャストは使いません。C++ の RepNotify はサーバー上では発火しません(JOJP0CvpB8w [00:10:50]、[00:14:48])。World Partition では BeginPlay が複数回実行されることがあるため、冪等性を保ちます(Shao KBn62trwkLw [00:07:29])。
- C++ を基底とし、Blueprint の子クラスはデータのみを持たせます。Blueprint は C++ に依存してもかまいませんが、その逆は不可です(Forsythe VMZftEVDuCE [00:24:10])。調整項目には
EditDefaultsOnly、アセットの選択にはTSubclassOfのスロット、コスメティック処理にはBlueprintImplementableEventのフックを使います。ロジックは差分を確認できるテキストに、Blueprint は Python セットのようにデフォルト値に使います。ブロードキャスターは一方向のデリゲート(OnDied)を発火し、コントローラー、スポナー、HUD がバインドします([00:19:25])。 - Blueprint のコストはノードごとにかかりますが、本当のコストはハード参照です。 CharacterMovement の更新と比べれば Tick のオーバーヘッドはわずかです。Blueprint クラスへのキャストは、そのクラスをキャスト元とともにロード状態にします(Arnbjörnsson S2olUc9zcB8 [00:06:07]、[00:28:01])。Insights のトレースでホットセットに入ったものだけを C++ に移します(Forsythe [00:16:33])。
- エフェクトは何が起きるか、アビリティはいつ起きるかを担います。 新機能はタグを通じて反応する新しいリアクティブアセットとして追加します。リアクションでは GE のアセットタグを参照し、SetByCaller を使ったダメージ GE を1つ用意します。Delay ではなく Wait Delay を使い、必ず End Ability を呼び出し、
PlayMontageAndWaitを使います。Gameplay Cues はコスメティック処理に限定します(Shao 8bi0rnXnRj4 [00:19:25]、[00:47:35]、[00:21:43]、[00:49:12]、[00:13:02]、tranek 9.3)。SetByCaller の値はコードが設定したときにのみ存在するため、コンソールでの切り分けテストには固定値の双子を使います[追加]。 - ASC は両側で接続します。 属性がリスポーン後も維持される必要がない限り、Pawn に配置します(必要な場合は PlayerState に配置します)。サーバーでは
PossessedByで、所有クライアントでは PlayerController のAcknowledgePossession(またはOnRep_PlayerState)でInitAbilityActorInfoを呼び出します。プレイヤーには Mixed、AI には Minimal を早い段階で設定し、ダメージは予測しません(tranek 4.1、4.1.2、7.3、4.10)。 - 入力は間接参照を伴うデータです。 Input Action から入力タグ、そしてアビリティへとつなげることで、Pawn にアビリティのロジックを持たせません(Noland、Lyra Fj1zCsYydD8 [00:34:33])。マッピングコンテキストはゲームプレイ状態ごとに相互排他的にします(フレームワークのドキュメント)。
- StateTree は遷移の前にリーフを選択し、遷移で要求されたときにのみ enter 条件を再確認します(Mononen YEmq4kcblj4 [00:11:22])。状態を終了させるべき各条件にはイベントまたは遷移が必要です。各状態には明示的な成功時と失敗時の抜け道を用意し、そうしないとルートにフォールバックします([00:14:13])。データはバインディングで渡し、調整項目はツリーパラメーターにします([00:16:40])。アクションはタイムアウト付きで Gameplay Ability に処理を委譲します(Bruno XKQfMZOXFv0 [00:17:37]、[00:19:15])。
- UI はプロパティバインディングではなくイベントで更新します。Global Invalidation を有効にしてから、フリーズしたウィジェットを探します(Albert VxX1aah6TZM [00:24:09])。ウィジェットの Tick は Paint から実行されます。テキストの変更はレイアウトの無効化を引き起こし、Hidden は再描画のみですが、Collapsed は再レイアウトを行います([00:10:09]、[00:13:56]、[00:12:53])。
最初に確認すること
| 入力項目 | 計画に影響する理由 | 指定がない場合の既定値 |
|---|---|---|
| シングルプレイヤーかマルチプレイヤーか、リッスンサーバーか専用サーバーか | ASC の配置、レプリケーションモード、予測、テストマトリクス | シングルプレイヤー。初日からオーソリティチェックを実施(ネットワーキングのドキュメント) |
| C++ ツールチェーン | Xcode 26.6 がインストール済み。Epic は 26.0 を最小要件、26.1.1 を推奨、26.4 を非互換としており、26.6 は未記載 | C++ を約束する前にビルドを検証(P3)。それ以外は Blueprint とデータの組み合わせを代替案とする |
| 規模 | 数十のアクターか、数百の静止インタラクタブルか、数千の移動体か | アクター。次に Instanced Actors、その後 Mass(KBn62trwkLw [00:01:06]) |
| 操作感の目標 | ジャンプの高さ、ダッシュ距離、クールダウン、歩行速度と追跡速度 | 確認する。CharacterMovement の既定値を変更しないと、「Unreal のチュートリアルプロジェクトのような操作感」になります(IaU2Hue-ApI [00:23:39]) |
| フレーム予算、プラットフォーム | Tick と AI の上限 | 60 fps。数値は scenario-unreal-performance に従う |
| キャラクターとレベルの入力データ | スケルトン、モンタージュ、通知。ナビゲーション範囲、プレイヤー開始地点、ストリーミング | scenario-unreal-animation および scenario-unreal-world-building に従う |
オーサリングの方法
スクリプトで扱えるもの:C++ クラス、Blueprint の子クラスとその CDO の既定値、データアセットとテーブル、Enhanced Input アセット、Gameplay Effect のシェル、StateTree アセットとパラメーター、ウィジェットツリー
(EditorUtilityLibrary.add_source_widget)。グラフコンテンツ(イベントグラフ、Python ではインスタンス化できない GE モディファイア、StateTree の状態と遷移、Behavior Tree ノード)は、バリアントごとに複製するテンプレート、Epic の MCP ツールセット、help() の後に 5.8 の BlueprintGraphEditor を使うか、GUI で一度だけ正確に操作して設定します。完全な一覧は手順 P15 を参照してください。
ワークフロー
- エンジンごとに一度プローブします。
job_00_gameplay_probe.py(ヘッドレス)は、スキルが [verify] とマークしたクラス、プロパティ、cvar を一覧表示します。これにはAbilitySystem.Fix...アセットタグ cvar とdumpticksのサンプルも含まれます。ゲート:probe.jsonが書き込まれていること。 - 方針を決定します。
ue_gameplay.decide(spec):データの配置、Blueprint と C++ のどちらを使うか、GAS を使うかどうか、AI システム、ASC の配置、初期化とレプリケーション、通信、UI、およびそれぞれの判断条件を決定します。ゲート:すべてのデータにオーナー、レプリケーション、保持条件(リスポーン、マップ変更、ストリーミング)が設定されていること。 - プロジェクトと設定をスキャフォールドします。
ue_env.enable_pluginsを使い、bUseDebugTargetFromHud、アセットタグ cvar を 0 に設定し、タグを設定するためにini_setを使います。showdebug用に GameMode の HUD クラスを設定します。ゲート:config_verdictに問題がないこと。 - C++ レイヤー。
cpp_scaffold()(キャラクターのベースクラス、プレイヤーコントローラー、ダッシュと近接攻撃のアビリティ、AI コントローラー、StateTree タスク、ヘルスウィジェット、ネイティブタグ)、patch_build_cs()、build_command()を使います。新しいリフレクションメンバーを追加する際はエディターを閉じます。ゲート:ビルドの終了コードが 0 であること。cpp_lintにエラーがないこと(ASC_CLIENT_INIT_MISSINGも含まれます)。 - Python からデータレイヤーを作成します。 Blueprint 子クラスと CDO のデフォルト値:移動、
JumpMaxCount = 2、GameMode のplayer_controller_class、およびすべての AI ポーンのai_controller_class= ツリーを保持するコントローラー Blueprint と、配置またはスポーンされたauto_possess_aiを設定します。input_plan()の入力アセット、ge_plan_verdictで検証したプランに基づく GE アセット、StateTree アセット、ウィジェットツリーを作成します。ゲート:ge_plan_verdictとaudit_gameplay()に問題がないこと。 - グラフの残作業。 各ツリーを仕様として記述し、
statetree_spec_verdictで検証します。MCP ツールセットまたは GUI での 1 回の作業を通じて、statetree_outlineから配線します(references/gui-paths.md)。敵ごとにツリーのパラメーターを設定します。ゲート:仕様の検証に問題がないこと。バインドされていない Inputs がなく、ツリーがコンパイルできること。ai_setup_verdictに問題がないこと。 - 単独でテストしてから、一連の流れをテストします。 コンソールから固定値のデバッグ GE を実行し、
showdebug abilitysystem(3 ページ)を表示します。各 AI で Gameplay Debugger を使い、log LogAbilitySystem VeryVerboseの出力をgas_log_triageで確認します。続いてpie_scenarioまたはInput.+key注入を使った PythonAutomationTest を実行し、パラメーターから導出したしきい値を持つアナライザー(analyze_jump、dash_expected_cm、analyze_cooldown、state_sequence_verdict、health_bar_verdict)で評価します。ゲート:すべてのシナリオに合格し、アビリティがスタックせず、予定外のルートエントリーがないこと。 - 証拠を記録してレビューします。 デバッグページ、
showdebug enhancedinput、ダメージ前後のヘルスバー、各状態の敵、ナビメッシュのカバレッジをスクリーンショットに収めます。確認の前にue_review.image_checksを実行します。ゲート:空白のフレームがなく、UI が同期していること。 - 計測します。 開発ビルドまたは新しいウィンドウでの PIE で、
stat game、stat unit、dumpticks(tick_verdict)、Global Invalidation の無効時と有効時のstat slate、およびリライト前のシナリオの Insights トレース(rewrite_gate)を実施します。ゲート:Tick の全数調査に根拠があり、ホットセット関数のみをリライトし、トレースを scenario-unreal-performance に渡していること。
数値
| 値 | 対象 | 出典 |
|---|---|---|
| アクターごとの Tick オーバーヘッド:BP はエディターで 3.59 us、パッケージ版で 1.84 us、C++ は約 0.64~0.70 us | 100,000 アクター、UE 5.4 | Arnbjörnsson [00:05:00] |
| CMC は 241 us、PlayerController はフレームあたり 125 us | 同じ Lyra フレーム | Arnbjörnsson [00:06:07] |
| BP ノードはパッケージ版で 0.1 us(エディターでは 0.5)、C++ 呼び出しは 0.7 us(エディターでは 0.8) | 呼び出しあたり | Arnbjörnsson [00:18:48] |
| Print String は呼び出しあたり 88.8~272.5 us | Development ビルド | Arnbjörnsson slides 00:20:10 |
| Fortnite:クライアントではフレームあたり約 80、サーバーでは 700 の Tick | Tick 関数 | Arnbjörnsson [00:11:03] |
| GetAllActorsOfClass はフレームあたり数十件程度の結果なら問題ありません。WithTag と WithInterface はすべてのアクターをスキャンします | ワールドサイズ | Arnbjörnsson [00:37:17], [00:38:56] |
| 空の Tick:5.6 から無料 | コンパイラーが無効化する | myth article |
| アクティブな敵の上限は 20 体、非同期パスのオフセットは 0.2~0.5 s、攻撃者は危険な敵 1 体または弱い敵最大 3 体 | Lords of the Fallen、コンソール、プレイヤーあたり | Bruno [00:16:25], [00:15:20], [00:38:40] |
| Lyra のモーダル表示で 207 個のウィジェットが再描画され、修正後は 25 個 | 描画回数 | Albert [00:35:03] |
| ジャンプの頂点の高さ h = v^2 / 2g。2 段目のジャンプでは Velocity.Z がリセットされ、ボタンを押した時点で高さ h が上昇量に加算されます | JumpZVelocity、重力 980 cm/s^2 × GravityScale | physics [added] |
| 地上ダッシュ = 速度 × 継続時間 + 終了時の惰性(600 cm/s で約 24 cm) | GroundFriction 8、BrakingFrictionFactor 2、BrakingDecelerationWalking 2048 | engine model [added, verify] |
品質ゲート
- 測定可能:
cpp_lint(アセットパスと依存関係の方向、マルチキャスト状態、Tick 内の Reliable RPC、サーバー上の OnRep、クライアントの ASC 初期化、ウィジェットの Tick、Collapsed の切り替え、BeginPlay の繰り返し);ge_plan_verdict;statetree_spec_verdict;ai_setup_verdict;audit_gameplay(Tick の全数調査、ハード参照の閉包、クールダウンタグ、ウィジェットのバインディング);派生しきい値を用いたシナリオ判定;gas_log_triageが空であること;showdebug abilitysystemでスタックしたアビリティがないこと;予定外のルートエントリーがない StateTree トレース;すべての書き換えの前にrewrite_gateを通すこと。 - 視覚: 固定カメラから見たジャンプの弧とダッシュ;敵の向きと間隔;体力バーとクールダウン UI が同期していること;Global Invalidation が有効な状態でウィジェットがフリーズしないこと;マルチプレイヤーで 2 クライアントのスクリーンショットが一致すること。
よくある間違い
| 間違い | どのような問題が起きるか | 修正方法 |
|---|---|---|
| GameMode に一時的なクライアントデータを置く | クライアントに何も表示されない | GameState または PlayerState |
| ドアの状態にマルチキャストを使う | 後から参加したプレイヤーにはドアが閉じて見える | レプリケーションプロパティ+RepNotify |
| プレイヤーからオプションの Blueprint にキャストする | ロードが長引き、メモリに常駐する | C++ の基底クラス、インターフェース、IsA(Soft) |
| 「Tick は使わない」と言いながら、毎フレーム Timeline を使う | コストは同じで、コードは複雑になる | Tick するアクターを減らし、集約し、間隔を設ける |
ASC を PossessedBy でしか初期化しない | クライアントで「Can't activate LocalOnly or LocalPredicted ability」が発生する | AcknowledgePossession または OnRep_PlayerState |
| アビリティが終了しない。中に Delay を置く | 再トリガーできず、キャンセル後も待機が続く | すべての経路でアビリティを終了する。Wait Delay |
| アビリティ内で PlayMontage を使う | 他のマシンでモンタージュが再生されない | PlayMontageAndWait |
| コンソールから SetByCaller GE を適用する | ダメージが 0 になり、マグニチュード不足のログが出る | 固定マグニチュードの同等版(GE_Damage_Debug) |
| GE 付与タグをクエリする | 誤ったエフェクトに対してリアクションが発生する | アセットタグを使う。アセットタグの cvar は 0 にする |
| エントリー条件がポーリングされると想定する | 攻撃範囲内でも敵が追跡を続ける | イベント、または実行中の状態での On Tick 遷移 |
| 失敗遷移のない状態 | 「なぜルートに戻ったのか」 | 成功と失敗の遷移を明示する |
| 1 つの状態で MoveTo の横に Delay を置く | 歩きながら待機する | Wait 状態を分ける。5.6 Task Control Flow |
| 敵の CDO に C++ コントローラークラスを設定する | 敵が動かない | ツリーを保持するコントローラー Blueprint を配置するかスポーンする |
| UMG プロパティバインディング、ウィジェットの Tick | フレームごとのコストがかかり、無効化中は更新が停止する | 属性デリゲートからのイベントを使う |
| 頻繁に切り替えるバーに Collapsed を使う | 切り替えのたびにレイアウトが無効化される | Hidden |
| ビューポートの PIE で無効化をテストする | 効果が見られない | 新しいウィンドウで PIE を実行する |
| プレイ中に同期保存する | ヒッチが発生し、認証リスクがある | AsyncSaveGameToSlot |
| 統計の当て推量から書き換える | 労力がかかるが、効果がない | Insights のトレース、rewrite_gate |
| テストのしきい値を手動で決める | 正しいビルドが失敗する | パラメーターから導き出す |
| エージェント Blueprint のタイマーを Delay チェーンにする | Delay ノードが 150 個になる(Deiter [00:56:45]) | Timeline、C++ タイマー、または GAS タスクを使う |
引き継ぎ
- 受け取るもの:scenario-unreal-animation からは、キャラクターの Blueprint 子クラス、変数の契約を定めた AnimBP、ルートモーションとワープターゲットを備えたモンタージュ、ヒットフレーム上の再利用可能な
AN_SendGameplayEventノーティファイを受け取ります。scenario-unreal-world-building からは、ナビゲーション境界、プレイヤースタート、ストリーミング範囲、Data Layers、Asset User Data としてのゲームプレイデータを受け取ります。 - 引き渡すもの:scenario-unreal-vfx にはイベント契約(
vfx_event_contract:タグ、トリガー、ゲームプレイデータ由来のペイロードと半径、ウィンドウ、最大レート、スポーンパス。キューは見た目上の効果のみ)を引き渡します。scenario-unreal-performance には、Development ビルド、オートメーションテストとしての最悪ケースシナリオ、その Insights トレース、Tick の集計、AI と ASC の数(perf_handoff)を引き渡します。scenario-unreal-animation には、モーションマッチング用データより前の段階の、調整済み移動モデルを引き渡します(DeVoe FLDXtAV7qsw [00:07:01])。scenario-unreal-pipeline-automation には、CI 用のオートメーションテストを引き渡します。
UE 5.8 に関する注意事項
- レプリケートされたプロパティは自動登録されます(5.6)。Iris はライセンシー向けに Production Ready ですが、汎用レプリケーションが引き続きデフォルトです。Mover は引き続き Experimental です。
- Enhanced Input は Common UI と統合されています(Production Ready)。Combo トリガーは非推奨です。
UPlayerMappableInputConfigは非推奨です(5.4)。 - GAS:NonInstanced アビリティは非推奨です(5.5)。クールダウン GE の検証(5.7)。Blueprint での
GetAssetTagsとGetGrantedTags(5.7)。デバッグコマンドはAbilitySystem.AbilityとAbilitySystem.Effect配下にあります(5.4)。 - StateTree:Task Control Flow とスケジュールされた Tick(5.6)。Rewind Debugger トラック(5.7)。タグによる開始ステート、リバーシブルバインディング、
UE::StateTree::EComparisonOperator(5.8)。 - Blueprint:ネイティブ化は削除されました(5.4)。IsA (Soft)(5.5)。空の Tick はコストがかかりません(5.6)。
BlueprintGraphEditor、メンバーと名前が重複するローカル変数の禁止、bp.MaxAsyncActionCount(5.8)。
参考資料
references/expert-notes.md:専門家ごとの原則、タイムスタンプ、見解の相違。references/procedures.md:各手順のコード全文、テストパス、ステータス。オーサリング画面(P15)。references/critique.md:エージェントが自身の出力に使用する評価基準。references/gui-paths.md:同じ作業に使用するエディター、メニュー、設定。references/sources.md:すべてのソース、認証情報、URL、最適なタイムスタンプ。scripts/ue_gameplay.py:判断、ひな形、Lint、GE と StateTree の仕様チェック、トレース分析、引き継ぎ。エディター内ヘルパー(未実行)。scripts/ue_gameplay_cpp.py:C++ ソーステンプレート(ロジックは C++ 基底クラス、データのみを持つ Blueprint 子クラス)。未コンパイル。