mcpField
U
unity-performance

unity-performance

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

unity-performance について

unity-performanceは、フレーム落ちやメモリ割り当てを調べるUnity開発者向けのコードレビュー用スキルです。明確な性能上の懸念を優先し、可能性の高い問題と根拠の乏しい微細な最適化を区別します。

主な機能

  1. 01高頻度の検索や更新ループを検出
  2. 02割り当てとプーリングの候補を特定
  3. 03見えにくい実行時コストを説明
  4. 04確度と影響度で指摘を整理

活用シーン

  1. 01Unityコードの性能リスクをレビュー
  2. 02フレーム落ちやカクつきを調査
  3. 03オブジェクトプーリングと割り当て削減を計画

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/besty0728/unity-skills --skill unity-performance

インストール後、Claude Code で/unity-performanceを入力して読み込まれたか確認します。

詳細

このモジュールのスキルを呼び出す前に: 名前や説明から推測したパラメーターを使ってスキルを呼び出そうとしている場合は、いったん停止し、先にこのファイルを読むか、GET /skills/recommend?includeSchema=true でスキーマを取得してください。recommend/schema からすでにパラメーター定義を取得している場合は、そのまま dryRun に進めます。

トリガー

  • パフォーマンスのレビュー
  • フレーム落ちの診断
  • メモリ割り当ての削減
  • プーリング/最適化の計画
  • パフォーマンスのレビュー、フレーム落ちやカクつきの診断、メモリ割り当ての削減、オブジェクトプール/最適化の計画

Unity のパフォーマンスに関する危険信号

Unity で起こり得るパフォーマンス上の問題を高い精度でレビューするには、このスキルを使用します。推測に基づくマイクロ最適化ではなく、危険信号に注目してください。

確認項目

  • 関係のない Update/LateUpdate/FixedUpdate ループが多すぎる
  • ホットパスで Find、GetComponent、Camera.main、タグ検索を繰り返している
  • プーリングに適した Instantiate/Destroy が頻繁に実行されている
  • 回避可能なフレームごとのメモリ割り当て:
    • LINQ
    • 文字列フォーマット
    • クロージャ
    • ボックス化
  • ランタイムのホットパスでリフレクションを使用している
  • エディター専用の高コストなヘルパーがランタイムコードに混入している
  • 物理演算、アニメーション、UI の更新頻度が適切でない

隠れたコスト:可能性 ≠ 実際の処理

一見「無料」に思えるものが、実際には高コストになる直感に反する落とし穴が 3 つあります。これらのコストは、実際に処理が行われたかどうかではなく、処理が行われる可能性に対して発生します。そのため、プロファイラーで直接検出することはほとんどできません。

書き込み権限は、書き込みを行わなくてもコストがかかる

Update 内で transform.position を変更できるコンポーネントは、その分岐が実行されなくてもコストを負担します。ダーティフラグやシリアライゼーションシステムは、書き込み権限を毎フレームのポーリングが必要な理由として扱うためです。同様に、実行時に一度も変更されない [SerializeField] フィールドも、シリアライゼーションの処理経路に残ります。解決策は分岐を厳しくすることではなく、権限を取り除くことです。まれにしか必要とされない書き込み処理を別のコンポーネントに分離し、必要になったときだけ AddComponent してください。出典:NetcodeSamples/HelloNetcode/2_Intermediate/07_Optimization/Optimization.md — 「コンポーネントに書き込む可能性があるシステムは、実際に書き込むかどうかに関係なく、常にシリアライズする必要がある」。

連続するシード値は相関した乱数列を生成する

N 個の RNG インスタンスに baseSeed + i をシードとして設定すると、N 個の類似した乱数列が生成されます。巡回経路が揃い、スポーン位置の揺らぎが偏り、戦利品の抽選結果が集中します。シード設定の前にインデックスをハッシュしてください:

// Wrong — N correlated streams
for (int i = 0; i < N; i++) rngs[i] = new System.Random(baseSeed + i);

// Correct — hash decorrelates adjacent seeds
for (int i = 0; i < N; i++)
    rngs[i] = new System.Random((int)((uint)baseSeed * 2654435761u ^ (uint)i));

Unity.Mathematics.Random.CreateFromIndex(i) はこれを内部で適用するため、数学パッケージが利用可能な場合はこの方法が推奨されます。出典:Dots101/Entities101/Assets/HelloCube/3. Prefabs/SpawnSystem.cs:37-39 およびそのコメント。

リリースビルドでもログはデフォルトで出力される

Debug.Log は Player ビルドで除去されません。引数が呼び出し元で省略されるのは、[Conditional("UNITY_EDITOR")] が付与されたメソッド(Debug.DrawLine など)だけです。つまり、文字列補間やヘルパー呼び出しを含むログ行は、リリースされたゲーム内でも毎フレーム実行されます:

// Wrong — GetPlayerInfo() and string interpolation execute in release
Debug.Log($"Player {GetPlayerInfo()} at {Time.time}");

// Better — guard the whole expression
if (Debug.isDebugBuild) Debug.Log($"Player {GetPlayerInfo()} at {Time.time}");

これは前述の「書き込みの可能性」のルールと同じ原則です。ランタイムは、実際の処理だけでなく、処理が行われる可能性に対してコストを負担します。

出力形式

  • 確認済みの危険信号
  • 可能性の高い危険信号
  • 今すぐ行う価値のある変更
  • 今すぐ行う価値のない変更
  • 期待できる効果の分類:明瞭さ/フレーム時間/GC/スケーラビリティ

ガードレール

モード:ドキュメントのみ — REST スキルによる制限はありません。どの動作モード(Approval/Auto/Bypass)でも自由に読み込めます。

  • 重大なホットスポットがない限り、大規模なリファクタリングを推奨しないでください。
  • ホットパスが実在するのでない限り、シンプルなコードを読みにくい「最適化済み」コードに置き換えないでください。

コメント