hz-unity-code-review について
hz-unity-code-reviewは、Meta VRヘッドセット向けUnity C#コードとプロジェクト設定を確認するスキルです。VR性能、レンダリング、入力、メモリ、物理、音声を重点的に扱い、metavrによるビルドとデバイスの検証も案内します。
主な機能
- 01Meta VRのレンダリング設定確認
- 02ドローコールとシェーダーの指針
- 03GC割り当てと高負荷箇所の確認
- 04コントローラー、手、視線入力の確認
- 05物理と音声設定の確認
- 06metavrによるデバイス検証の案内
活用シーン
- 01UnityコードのVR性能問題のレビュー
- 02レンダリングとXR設定の監査
- 03複数のVR入力方式への対応確認
- 04接続したMeta VRデバイスでのビルド検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ meta-quest/ agentic-tools --skill hz-unity-code-reviewインストール後、Claude Code で/hz-unity-code-reviewを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/common-pitfalls.mdinput-handling.mdperformance-checklist.mdrendering-best-practices.md詳細
Meta VR 向け Unity コードレビュー
使用するタイミング
Meta VR ヘッドセットを対象とする Unity の C# コードまたはプロジェクト設定をレビューする際に、このスキルを使用します。次の内容が含まれます。
- VR のパフォーマンス上の問題についてスクリプトをレビューする
- レンダリングパイプラインの構成と設定を確認する
- Meta VR 固有のベストプラクティスへの準拠を確認する
- VR 開発でよくある落とし穴を特定する
- コントローラー、ハンドトラッキング、アイトラッキングの入力処理を検証する
- メモリ使用量と GC 割り当てのパターンを監査する
主なレビュー項目
1. レンダリングパイプラインの構成
Meta VR アプリケーションでは、モバイル VR 向けに最適化された特定の設定を使用して、Universal Render Pipeline(URP)を利用する必要があります。新しい Meta VR プロジェクトでは、Built-in Render Pipeline は推奨されません。
確認が必要な重要な設定:
- シングルパス・マルチビューを有効にする必要があります(Player Settings > XR Plug-in Management > Oculus > Stereo Rendering Mode)
- Vulkanを主要なグラフィックス API にする必要があります
- 正しいライティングにはリニアカラースペースが必要です
- URP アセットの設定でHDRを無効にする必要があります
- ポストプロセッシングは最小限にするか、無効にする必要があります
2. ドローコール予算とバッチ処理
Meta VR のドローコール予算は、ワークロードの複雑さによって異なります。各ドローコールには CPU オーバーヘッドがあり、フレームタイミングに直接影響します。
| 指標 | Quest 2 / Quest Pro | Quest 3 / Quest 3S | Meta VR Glasses |
|---|---|---|---|
| ドローコール(高負荷のシミュレーション) | 80-200 | 200-300 | 200-300 |
| ドローコール(中負荷のシミュレーション) | 200-300 | 400-600 | 400-600 |
| ドローコール(低負荷のシミュレーション) | 400-600 | 700-1000 | 700-1000 |
| 1 フレームあたりの三角形数 | 750K-1M | 1M-2M | 1M-2M |
| SetPass 呼び出し | < 50 | < 80 | < 80 |
次の項目を有効にし、確認してください。
- 移動しないジオメトリにはスタティックバッチングを使用する
- 繰り返し配置されるオブジェクトには GPU インスタンシングを使用する
- URP マテリアルには SRP Batcher を使用する
- 小さなメッシュ(< 300 頂点)にはダイナミックバッチングを使用する
3. シェーダーの複雑さ
Meta VR のモバイル GPU では、デスクトップクラスのシェーダーを処理できません。すべてのマテリアルについて、次の項目を確認してください。
- Standard シェーダーではなく、URP/Lit または URP/Simple Lit を使用している
- カスタムシェーダーでテクスチャサンプルと ALU 演算を最小限に抑えている
- 可能な限りリアルタイムシャドウを避けている(代わりにベイクする)
- スクリーンスペースエフェクトを使用していない(SSAO、SSR、スクリーンスペースシャドウ)
4. メモリ管理
GC 割り当てはフレームのひっかかりを引き起こすため、ホットパスから排除する必要があります。
// BAD: Allocates every frame
void Update() {
string label = "Score: " + score.ToString();
var enemies = FindObjectsOfType<Enemy>();
var filtered = enemies.Where(e => e.IsAlive).ToList();
}
// GOOD: Zero allocations in Update
private StringBuilder _sb = new StringBuilder(32);
private List<Enemy> _enemyCache = new List<Enemy>();
private Enemy[] _enemyArray;
void Start() {
_enemyArray = FindObjectsOfType<Enemy>();
}
void Update() {
_sb.Clear();
_sb.Append("Score: ");
_sb.Append(score);
}
5. 入力処理
Meta VR は複数の入力方式をサポートしています。コードでは次の入力を処理できるようにしてください。
- コントローラー:新しいプロジェクトでは Unity の Input System Package を使用します(推奨)。
OVRInputはレガシーサポート向けに保守されています - ハンドトラッキング:ハンドポーズデータには
OVRHandとOVRSkeletonを使用します - アイトラッキング:
OVREyeGaze(Quest Pro / Meta VR Glasses。許可が必要です) - コントローラーとハンドトラッキングのモードをスムーズに切り替える
6. 物理設定
モバイルでは物理シミュレーションの負荷が高くなります。次の項目を確認してください。
- 物理タイムステップを目標フレームレート(72/90/120 Hz)に合わせる
- 衝突メッシュを単純化する(メッシュコライダーではなくプリミティブを使用する)
- ソルバー反復回数を減らす(通常は 4-6 で十分です)
- ペアチェックを最小限に抑えるレイヤーベースの衝突マトリックスを使用する
- Rigidbody のスリープしきい値を適切に設定する
7. オーディオ設定
見落とされがちなオーディオも、パフォーマンスに影響することがあります。
- オーディオクリップを圧縮する(音楽には Vorbis、短い SFX には ADPCM を使用する)
- 1 秒を超えるクリップにはストリーミングのロードタイプを使用する
- 同時に再生するオーディオソースを制限する(目標は < 16)
- 3D 位置の再現には Meta のオーディオ SDK を使用してオーディオを空間化する
クイックレビューのチェックリスト
| 項目 | 目標 | 備考 |
|---|---|---|
| ドローコール | 高負荷時は80~200、低負荷時は400~600 | バッチ処理、インスタンシング、アトラス化を使用します |
| 三角形 | 1フレームあたり750K~1M | LOD、オクルージョンカリングを使用します |
| テクスチャ解像度 | 最大2K、4Kは控えめに使用 | ASTC圧縮が必須です |
| シェーダー | URPモバイルシェーダー | Standardシェーダーやスクリーンスペースエフェクトは使用しません |
| レンダリングモード | シングルパスマルチビュー | XR設定で有効にする必要があります |
| FFR | 有効(HighまたはHighTop) | 固定フォービエイテッドレンダリングにより、画面端のフラグメント処理コストを削減します |
| MSAA | 品質重視なら4x、パフォーマンス重視なら2x | 正しく設定すれば、タイルベースGPUでは追加コストなしで利用できます |
| 目標フレームレート | 最低72 Hz | 90 Hzを推奨。滑らかな体験には120 Hzが適しています |
| GC割り当て | 定常状態で0 B/frame | Update/LateUpdate/FixedUpdate内では割り当てを行いません |
| オーディオソース | 同時に16未満 | オーディオソースにはプーリングを使用します |
コードで確認する項目
GC負荷の高いパターン
// Flag these patterns in code review:
Camera.main // Calls FindWithTag internally
GameObject.Find("name") // Linear search every call
GetComponent<T>() in Update // Cache the result
new List<T>() in Update // Allocates on heap
string + string in Update // Creates new string objects
foreach on non-List collections // Enumerator allocation
LINQ queries (.Where, .Select) // Multiple allocations
Boxing (int -> object) // Heap allocation
delegate/lambda in hot paths // Closure allocation
Update()の誤用
// BAD: Empty Update still has overhead
void Update() { }
// BAD: Logic that doesn't need per-frame execution
void Update() {
SavePlayerPrefs(); // Should be event-driven
}
// GOOD: Use events, coroutines, or InvokeRepeating for non-per-frame logic
void OnScoreChanged(int newScore) {
UpdateScoreUI(newScore);
}
Camera.mainのアンチパターン
// BAD: Camera.main uses FindWithTag internally
void Update() {
transform.LookAt(Camera.main.transform);
}
// GOOD: Cache the reference
private Transform _cameraTransform;
void Start() {
_cameraTransform = Camera.main.transform;
}
void Update() {
transform.LookAt(_cameraTransform);
}
ホットパス内のFind呼び出し
// BAD: Expensive search every frame
void Update() {
var player = GameObject.FindWithTag("Player");
var rb = player.GetComponent<Rigidbody>();
}
// GOOD: Cache in Awake/Start or use dependency injection
private Rigidbody _playerRb;
void Awake() {
_playerRb = GameObject.FindWithTag("Player").GetComponent<Rigidbody>();
}
検証にmetavrを使用する
ビルドを検証し、デバイス上の動作を確認するには、metavrツールを使用できます。metavr <args>で実行します(npmパッケージmetavrとして公開されています。metavrがPATH上にない場合は、npx -y metavr <args>を実行してください)。インストールは不要です。
# Check connected Meta VR device
metavr device list
# Install and run a build
metavr app install path/to/build.apk
metavr app launch com.company.app
# Check device logs for errors
metavr adb logcat --tag Unity
# Monitor GPU performance
metavr perf capture
コードレビューで見つかった問題が実際のパフォーマンス改善につながることを、デバイス上のプロファイリングで検証してください。
参考ドキュメント
各トピックの詳細なガイダンスについては、以下の参考ドキュメントを参照してください。
- パフォーマンスチェックリスト — パフォーマンス目標と最適化戦略の包括的なガイド
- レンダリングのベストプラクティス — Meta VR固有のレンダリング設定とシェーダーのガイドライン
- 入力処理 — コントローラー、ハンドトラッキング、アイトラッキングの実装
- よくある落とし穴 — 頻繁に発生する間違いとその修正方法