mcpField
U
unity-performance

unity-performance

github.com/josiahsiegel開発59100 回インストール19 週間前に更新
リポジトリ

unity-performance について

Unity ゲーム開発者向けに、性能の計測と最適化を解説するリファレンスです。CPU、GPU、メモリ、描画、プラットフォーム別の対策を、計測と比較を繰り返す手順とともに扱います。

主な機能

  1. 01Unity のプロファイリング手順
  2. 02CPU とガベージコレクションの最適化
  3. 03GPU と描画の最適化手法
  4. 04メモリとアセット読み込みのガイド
  5. 05プラットフォーム別の性能上の注意

活用シーン

  1. 01対象デバイスでフレーム時間のボトルネックを調査
  2. 02ゲーム中の割り当てやオブジェクト生成を削減
  3. 03複雑なシーンの描画を最適化
  4. 04各プラットフォームのメモリとアセット読み込みを管理

インストール

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

$npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill unity-performance

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

詳細

Unity のパフォーマンス最適化

概要

Unity ゲームのプロファイリングと最適化を体系的に行う方法です。プロファイリングツール、CPU/GPU の最適化、メモリ管理、レンダリングの最適化、プラットフォーム固有の考慮事項を扱います。

プロファイリングツール

ツール表示される内容使用する場面
Unity Profilerフレームごとの CPU、GPU、メモリ、オーディオ、物理演算パフォーマンスの問題が発生した際の最初の調査
Frame Debuggerドローコールの内訳、シェーダー/マテリアルの状態レンダリングのボトルネック
Memory Profilerヒープスナップショット、テクスチャ/メッシュのメモリ使用量メモリリーク、メモリの肥大化
Profile Analyzerキャプチャの比較、統計分析最適化の前後の比較
Physics Debuggerコライダーの可視化、接触点物理演算のパフォーマンス
Profiler のワークフロー
  1. Development Build と Autoconnect Profiler を有効にしてビルドします
  2. 対象デバイス上でプロファイリングします(Editor 上ではなく、Editor のオーバーヘッドによって結果が歪むため)
  3. ボトルネックのカテゴリを特定します:CPU バウンド、GPU バウンド、またはメモリ不足
  4. 問題の原因となっているシステムを詳しく調べます
  5. 最適化し、再度プロファイリングして比較します
Profiler の読み方
If frame time > 16.6ms (60 FPS target):
  CPU timeline > GPU timeline -> CPU-bound
  GPU timeline > CPU timeline -> GPU-bound
  GC.Alloc column shows per-frame allocations -> GC pressure

スパイク(単発の遅いフレーム)と、高い時間が継続する状態(ベースラインが重すぎる状態)を確認します。

CPU の最適化

フレームごとの割り当て(GC)を減らす
アンチパターン修正方法
Update 内での string + stringStringBuilder を使用するか、キャッシュします
フレームごとの new List<T>()一度だけ割り当て、Clear() して再利用します
ホットパスでの LINQ手動のループに置き換えます
フレームごとの GetComponent<T>()Awake/Start でキャッシュします
フレームごとの GameObject.Find()参照をキャッシュするか、イベントを使用します
ジェネリックではないコレクションに対する foreachfor ループまたはジェネリックコレクションを使用します
SendMessage() / BroadcastMessage()直接呼び出し、イベント、またはインターフェースを使用します
値型のボックス化ジェネリックコレクションを使用し、object へのキャストを避けます
オブジェクトプーリング
public class ObjectPool<T> where T : Component
{
    readonly Queue<T> _pool = new();
    readonly T _prefab;
    readonly Transform _parent;

    public ObjectPool(T prefab, int preWarm, Transform parent = null)
    {
        _prefab = prefab;
        _parent = parent;
        for (int i = 0; i < preWarm; i++)
            _pool.Enqueue(CreateInstance());
    }

    public T Get(Vector3 position, Quaternion rotation)
    {
        var obj = _pool.Count > 0 ? _pool.Dequeue() : CreateInstance();
        obj.transform.SetPositionAndRotation(position, rotation);
        obj.gameObject.SetActive(true);
        return obj;
    }

    public void Return(T obj)
    {
        obj.gameObject.SetActive(false);
        _pool.Enqueue(obj);
    }

    T CreateInstance()
    {
        var obj = Object.Instantiate(_prefab, _parent);
        obj.gameObject.SetActive(false);
        return obj;
    }
}

頻繁に生成/破棄される弾丸、パーティクル、敵、UI 要素など、あらゆるものをプールします。Unity 2021+ には UnityEngine.Pool.ObjectPool<T> も組み込まれています。

Update の最適化
手法説明
更新を分散するすべての AI を毎フレーム更新せず、ティックグループを使用します
距離ベースの LOD遠くのオブジェクトの更新頻度を下げます
イベント駆動可能な場合はポーリングをイベントに置き換えます
未使用のスクリプトを無効にする画面外のコンポーネントで enabled = false にします
InvokeRepeating を使用する定期的なチェックに使用します(コルーチンで待機するより低コストです)

GPU/レンダリングの最適化

ドローコールを減らす
手法方法削減効果
Static Batching移動しないオブジェクトを Static に設定しますビルド時にメッシュを結合します
Dynamic Batching小さなメッシュ(<300 verts)に対して自動で行われますURP/Built-in のみ
GPU Instancing繰り返し表示するオブジェクトのマテリアルで有効にします木、草、岩
SRP BatcherURP/HDRP でデフォルトで有効ですSetPass 呼び出しを減らします
テクスチャアトラス化テクスチャをアトラスにまとめますマテリアルの切り替えを減らします
メッシュの結合実行時に CombineMeshes() を使用しますカスタムバッチング
LOD(詳細度)
LOD Group Setup:
  LOD 0 (0-30%):  Full-detail mesh (5000 tris)
  LOD 1 (30-60%): Medium mesh (2000 tris)
  LOD 2 (60-90%): Low mesh (500 tris)
  Culled (90%+):  Not rendered

メッシュに LOD を使用するだけでなく、遠距離ではスクリプトの複雑さ、パーティクル数、物理演算も減らします。

オクルージョンカリング

屋内や複雑なシーンではオクルージョンデータをベイクします。壁や床など、大きな静的オクルーダーを設定します。シーンのスケールに合わせてセルサイズを設定します。Occlusion Culling ウィンドウを使用して可視化し、テストします。

シェーダーの最適化
問題解決策
複雑なフラグメントシェーダーテクスチャサンプルを減らし、計算を簡略化します
オーバードロー透明オブジェクトを最小限にし、可能な場合は不透明にします
バリアントが多すぎるビルド設定で未使用のシェーダーバリアントを除外します
高コストなポストプロセッシングモバイルではエフェクトを無効にし、より低コストな代替手段を使用します

メモリ管理

メモリに関するよくある問題
問題症状対処方法
テクスチャの肥大化メモリ使用量が多く、読み込みに時間がかかるテクスチャを圧縮し、プラットフォームごとに最大サイズを小さくします
アンロード済みシーンが参照を保持時間とともにメモリ使用量が増加するシーン遷移後に Resources.UnloadUnusedAssets() を使用します
Addressables が解放されないバンドルがメモリに残るAddressables.Release(handle) を呼び出します
オーディオクリップが非圧縮メモリ使用量が非常に大きい音楽はメモリ上で圧縮し、効果音は読み込み時に展開します
メッシュの読み取り/書き込みが有効メッシュごとにメモリ使用量が倍増する実行時に不要であれば Read/Write を無効にします
プラットフォームごとのテクスチャ圧縮
プラットフォーム形式備考
PC/ConsoleBC7 (DXT)品質とサイズの比率が最適です
AndroidASTC 6x6汎用的で、品質を調整できます
iOSASTC 6x6Android と同じです
WebGLETC2 / DXT対象 GPU によって異なります

テクスチャのインポート設定で「Override for [Platform]」を使用します。最大テクスチャサイズは必要最小限に設定します(UI アイコンは 512、プロップは 1024、ヒーローアセットは 2048)。

プラットフォーム固有の考慮事項

プラットフォーム主な制約
Mobileサーマルスロットリング、限られたメモリ、バッテリー消費、フィルレートの制限
WebGLスレッド非対応(Unity 6 より前)、ダウンロードサイズが大きい、コンピュートシェーダー非対応
Console認定要件、固定されたハードウェア、メモリ予算
VR/XR最低 72~90 FPS、ステレオレンダリングの負荷、フレームレート低下による乗り物酔い

Addressables とアセットの読み込み

読み込み時のカクつきを避けるため、非同期アセット読み込みには Addressables を使用します。

// Preload during loading screen
var handle = Addressables.LoadAssetAsync<GameObject>("enemy_boss");
await handle;

// Release when done
Addressables.Release(handle);

Addressable グループを使用して、バンドルの粒度を制御します。使用頻度の低いアセットはリモート/オンデマンドとして設定します。Addressables Event Viewer でバンドルのメモリ使用量をプロファイリングします。

最適化のクイックチェックリスト

  • Editor ではなく、対象デバイスでプロファイリングする
  • ゲームプレイコードでフレームごとの GC 割り当てをゼロにする
  • 頻繁に生成されるすべてのオブジェクトにオブジェクトプーリングを使用する
  • 動かないオブジェクトでスタティックバッチングを有効にする
  • 距離に応じて表示されるすべての 3D モデルに LOD グループを設定する
  • プラットフォームに応じた適切な最大サイズでテクスチャを圧縮する
  • 実行時に変更しないメッシュとテクスチャでは Read/Write を無効にする
  • オーディオクリップに適切な圧縮設定を使用する
  • 屋内や複雑なシーンではオクルージョンカリングをベイクする
  • ビルド設定でシェーダーバリアントを除外する

追加リソース

参考ファイル
  • references/profiling-deep-dive.md -- Profiler の高度な使用方法、メモリプロファイラーのスナップショット、フレームごとの分析、カスタムプロファイラーマーカー、自動パフォーマンステスト、ビルドサイズ分析、ECS/DOTS のパフォーマンスパターン

コメント