mcpField
H
hz-unity-code-review

hz-unity-code-review

github.com/meta-quest测试与质量241249 次安装5 周前更新
代码仓库

关于 hz-unity-code-review

hz-unity-code-review 是用于审查面向 Meta VR 头显的 Unity C# 代码和项目设置的技能,重点检查性能、渲染、输入、内存、物理和音频,并介绍使用 metavr 验证构建和设备行为。

主要功能

  1. 01审查 Meta VR 渲染设置
  2. 02绘制调用与着色器指南
  3. 03检查 GC 分配和热点代码
  4. 04审查控制器、手势与眼动输入
  5. 05检查物理和音频配置
  6. 06metavr 设备验证指南

适用场景

  1. 01审查 Unity 代码中的 VR 性能问题
  2. 02检查渲染和 XR 项目设置
  3. 03核对多种 VR 输入方式的处理
  4. 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.md
input-handling.md
performance-checklist.md
rendering-best-practices.md

详细介绍

面向 Meta VR 的 Unity 代码审查

使用时机

在审查面向 Meta VR 头显的 Unity C# 代码或项目设置时使用此技能。包括:

  • 审查脚本中的 VR 性能问题
  • 检查渲染管线配置和设置
  • 确保遵循 Meta VR 特定的最佳实践
  • 识别常见的 VR 开发陷阱
  • 验证控制器、手部和眼动追踪的输入处理
  • 审计内存用量和 GC 分配模式

重点审查领域

1. 渲染管线配置

Meta VR 应用必须使用经过特定设置优化的通用渲染管线(URP),以适配移动 VR。不建议在新的 Meta VR 项目中使用内置渲染管线。

需要核查的关键设置:

  • 必须启用单通道多视图(Player Settings > XR Plug-in Management > Oculus > Stereo Rendering Mode)
  • Vulkan 应作为主要图形 API
  • 必须使用线性颜色空间,以确保光照正确
  • 应在 URP 资源设置中禁用 HDR
  • 后期处理应尽量精简或禁用
2. 绘制调用预算与批处理

Meta VR 的绘制调用预算因工作负载复杂度而异。每次绘制调用都会带来 CPU 开销,直接影响帧时间。

指标Quest 2 / Quest ProQuest 3 / Quest 3SMeta VR Glasses
绘制调用(繁忙模拟)80-200200-300200-300
绘制调用(中等模拟)200-300400-600400-600
绘制调用(轻量模拟)400-600700-1000700-1000
每帧三角形数750K-1M1M-2M1M-2M
SetPass 调用< 50< 80< 80

启用并核查:

  • 对非移动几何体启用静态批处理
  • 对重复对象启用 GPU 实例化
  • 对 URP 材质启用 SRP Batcher
  • 对小型网格(< 300 个顶点)启用动态批处理
3. 着色器复杂度

Meta VR 上的移动 GPU 无法处理桌面级着色器。审查所有材质,确保:

  • 使用 URP/Lit 或 URP/Simple Lit,而不是 Standard 着色器
  • 自定义着色器尽量减少纹理采样和 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,短音效使用 ADPCM)
  • 对长度超过 1 秒的片段使用流式加载类型
  • 限制同时播放的音频源数量(目标 < 16)
  • 使用 Meta 的音频 SDK 对音频进行空间化,实现 3D 定位

快速审查清单

范围目标说明
绘制调用80-200(繁忙场景)至 400-600(轻量场景)使用批处理、实例化和图集
三角形数量750K-1M/帧使用 LOD 和遮挡剔除
纹理分辨率最高 2K,谨慎使用 4K必须使用 ASTC 压缩
着色器URP 移动端着色器不使用 Standard 着色器或屏幕空间效果
渲染模式单通道多视图必须在 XR 设置中启用
FFR已启用(High 或 HighTop)固定注视点渲染可降低边缘片元开销
MSAA4x 画质 / 2x 性能配置正确时,在基于 tile 的 GPU 上无需额外开销
目标帧率最低 72 Hz建议 90 Hz,流畅体验可使用 120 Hz
GC 分配稳定运行时为 0 B/帧不要在 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

使用设备端性能分析,验证代码审查中的发现是否能带来实际性能提升。

参考文档

如需了解特定主题的详细指南,请参阅以下参考文档:

评论

支持 Markdown