Unity ゲームパフォーマンス最適化まとめ
Unityでのボトルネック特定から、特に「物理演算(Physics)」が支配的な場合の具体的な対策(Vampire Survivors系ゲームを想定)についてのまとめ。
1. パフォーマンス分析の基本
最適化の鉄則は 「推測するな、計測せよ」。
Profiler(プロファイラー)の活用
Window > Analysis > Profiler を開き、以下の3点を確認する。
- CPU Usage: スクリプト、物理演算、UI更新の負荷。
- GPU Usage: ポリゴン数、シェーダー、ドローコールの負荷。
- Memory: GC(ガベージコレクション)によるスパイク(カクつき)の有無。
2. カテゴリ別最適化案
■ CPU(スクリプト・処理)
-
キャッシュの利用:
Update内でのGetComponentやFindを避け、Startで変数に代入しておく。 - 処理の間引き: 毎フレーム実行する必要のない処理は、数フレームに1回、あるいはコルーチンで実行する。
-
オブジェクトプール:
Instantiate/Destroyを避け、非アクティブなオブジェクトを再利用する。
■ GPU(描画)
-
ドローコールの削減: 静的オブジェクトを
Static設定にする。同じマテリアルを使い、バッチング(SRP Batcher等)を効かせる。 - Overdraw対策: 透明なUIやエフェクトの重なりを最小限にする。
- LOD (Level of Detail): 遠くのモデルのポリゴン数を下げる。
3. 物理演算(Physics)の深掘り対策
物理演算がCPU負荷の多くを占める場合の具体的なアプローチ。
コライダーの軽量化
-
プリミティブコライダーの使用:
Mesh Colliderを廃止し、Box,Sphere,Capsuleを組み合わせる。 -
Convex設定: どうしてもメッシュを使う場合は
Convexにチェックを入れる。
設定の最適化
-
Layer Collision Matrix:
Project Settings > Physicsで、衝突判定が不要なレイヤー同士(例:敵同士、アイテムと敵など)のチェックを外す。 -
Fixed Timestepの調整:
0.02(50fps)を0.033(30fps)程度に下げる。カクつきは Rigidbody のInterpolateで補完する。 -
Rigidbodyの管理: 動かすものには必ず Rigidbody を付け、スクリプトで動かす場合は
isKinematicをONにする。
4. 大量オブジェクト(Vampire Survivors系)の戦略
数千〜数万の敵やオーブを出す場合の「物理エンジンを使わない」最適化。
物理の代用
-
距離ベースの判定: 経験値オーブなどは Physics を使わず、
sqrMagnitude(二乗距離)でプレイヤーとの距離を測り、スクリプトで吸い寄せる。 - 敵の押し合い: 物理演算の代わりに、自分に近い敵から離れる「分離ベクトル」を計算して移動に加算する。
空間分割(Spatial Partitioning)
- 画面をグリッド(格子)に分割し、同じマスにいるオブジェクト同士のみ判定を行うことで、計算量を $O(N^2)$ から劇的に減らす。
高度な技術(Unity 6 / DOTS)
- DOTS (ECS + Job System + Burst): 大量のデータを並列処理するための最新アーキテクチャ。物理演算を数万単位で回す場合に必須。
- GPU Instancing: 大量の同一オブジェクトを1回のドローコールで描画する。
- Compute Shader: 大量の移動計算(例:オーブの追従)をGPU側で一括処理する。
[!TIP]
物理計算のコツ
距離計算でVector3.Distanceを使うと内部で平方根(重い処理)を計算します。
比較するだけなら(a - b).sqrMagnitudeを使うと高速です。