mcpField
Q
quest-native

quest-native

github.com/ssheleg开发197 次安装6 天前更新
代码仓库

关于 quest-native

面向使用 C 或 C++、OpenXR 和 Android 开发 Horizon OS 应用的 Agent 技能。它聚焦原生开发中容易出错的兼容边界,并要求在采用 API 和配置前核对 Meta 文档。

主要功能

  1. 01判断项目适用的开发技术路线
  2. 02核验 Meta API 与文档
  3. 03配置开发和发布 manifest
  4. 04处理 SDK 级别与 OpenXR 加载器
  5. 05实现会话、帧循环与焦点规则
  6. 06按能力检测设备功能

适用场景

  1. 01检查原生 Quest 项目的 manifest
  2. 02排查 OpenXR 加载器启动问题
  3. 03实现焦点切换时持续渲染
  4. 04确认 Horizon OS API 和 SDK 要求

MCP 相关

技能通过 metavr MCP 服务搜索 Meta 文档;该服务提供与 CLI 相同的文档搜索能力。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/ssheleg/xr-dev --skill quest-native

安装后在 Claude Code 中输入/quest-native确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
doc-map.md
frame-loop.md
manifest-and-gradle.md
mixed-reality.md
project-playbook.md

详细介绍

Horizon OS 上的原生 OpenXR

使用 C 或 C++ 编写的 Quest 应用通过 OpenXR 与头显通信,并通过 Android 与底层的手机级操作系统通信。大多数问题都出在这两者的衔接处:清单文件在侧载时合法、在商店审核时却不合法;加载器版本导致崩溃,而不是降级运行;一旦失去焦点,帧循环就停止绘制。

阅读 references/project-playbook.md,了解项目探索、目标/版本约定、引擎交接、纵向切片和审计。阅读 references/mixed-reality.md,了解功能/权限决策、追踪/空间生命周期、同地协作,以及摄像头或 AI 输入。

如果要规划整个产品路线图或进行阶段审计,请使用 quest-lifecycle;单个技术任务仍由本技能负责。如果该技能不存在,请直接指出当前阶段、相关证据和下一个前置条件。

步骤 0——这个项目真的适用这条路径吗?

项目类型负责方
使用 C / C++、面向 OpenXR,采用 Gradle + NDK本技能
UnityMeta 的 hz-unity-* 技能(共 12 个:核心 SDK、MRUK、移动/重定向、quest-ui、透视摄像头、放置、平台 SDK、项目分析器、TMP、FBX 导入、面部追踪、代码审查)
Unrealhttps://developers.meta.com/horizon/llmstxt/documentation/unreal/llms.txt/
Kotlin / Spatial SDKMeta 的 hz-spatial-sdk
WebXR、IWSDK、PWA本工具包中的 quest-webxr
现有的 2D Android 应用Meta 的 hz-android-2d-porting

选错路径造成的损失比本文档中的任何单个 bug 都大:Unity 相关的解答无法直接用于 NativeActivity,OpenXR 扩展名称也无法直接用于 Unity 的 OVR 封装。

步骤 1——先验证,再回答

Horizon OS 按自己的节奏发布,API 表面也随之变化。凡是涉及 Quest API、所需 SDK 级别或清单元素的说法,在写入代码之前都要先对照 Meta 官方文档核验:

metavr docs search "openxr swapchain"          # the CLI; the MCP server exposes the same search

每个文档页面都有对应的 Markdown 版本——无需抓取 HTML,也无需登录:

index:  https://developers.meta.com/horizon/llmstxt/documentation/native/llms.txt/
page:   https://developers.meta.com/horizon/llmstxt/documentation/native/android/<slug>.md

references/doc-map.md 收录了值得牢记的文档 slug。如果已安装 Meta 的 hz-quest-verify-first 技能,它会自行执行此项检查——请查看其结果,而不要重复搜索。

步骤 2——清单文件,其实有两套

开发要求和发布要求有所不同,审核时只会强制检查发布要求(VRC.Quest.Packaging.1、.4)。编写开发用清单文件并提交,却不检查发布要求的差异,可能导致审核失败。

沉浸式 OpenXR 应用当前的 Meta 清单片段(已于 2026-09-21 重新核验):

<uses-feature android:name="android.hardware.vr.headtracking"
              android:required="true" android:version="1" />

<intent-filter>
  <action   android:name="android.intent.action.MAIN" />
  <category android:name="android.intent.category.LAUNCHER" />
  <category android:name="com.oculus.intent.category.VR" />
</intent-filter>
  • android.hardware.vr.headtracking 中的 required="true" 会将应用标记为沉浸式应用;2D 面板应用应省略此项或将其设为 required="false"。
  • android:screenOrientation="landscape"、主题 Theme.Black.NoTitleBar.Fullscreen,以及清单文档列出的完整 configChanges 列表。绝不要使用 noHistory。
  • 仅发布时:android:debuggable 设为 false 或省略,installLocation="auto",使用唯一的 android:label,并通过 com.oculus.supportedDevices 列出 quest2|questpro|quest3|quest3s——不在该列表中的设备会以兼容模式运行,并将自身报告为较旧一代设备。
  • 纯 NativeActivity 应用可以使用 android:hasCode="false" 发布。Platform SDK 是一个 Java 库;添加它后就不能再使用该选项。

完整的逐项约定以及两套清单的并列对照: references/manifest-and-gradle.md。

步骤 3 — SDK 级别:2026 年发生了变化

适用于仍受支持的设备(Quest 2、Pro、3 系列)的推荐设置:minSdk 32、 targetSdk 34、compileSdk ≥ targetSdk。合法范围为 minSdk 29–34,沉浸式应用的 targetSdk 为 32–34(2D 面板应用为 32–36)——但自 2026 年 3 月 1 日起创建的应用必须以 34 为目标版本。固定这些值之前,请先阅读源文件中的两张表;表格附有日期,见 references/manifest-and-gradle.md。

锁定文件不等于构建配置。 搜索 build.gradle 和项目使用的所有依赖锁定文件:2026-09-20,在某个 Quest 项目中,gradle 写的是 targetSdk 34,而 dependencies.lock.json 仍写着 32。这份发行说明描述的是一个并不存在的构建。

步骤 4 — 加载器,以及任何代码之前必须启用的两个扩展

android { buildFeatures { prefab true } }
dependencies { implementation 'org.khronos.openxr:openxr_loader_for_android:<ver>' }
  • Meta 支持 Khronos Android 加载器;已不存在专有加载器。低于 1.0.34 时应用会崩溃——不会回退到其他加载器。
  • 使用 Khronos 加载器的应用在低于 v62 的 Horizon OS 上会崩溃,而 v62 以下的非 Quest 1 用户永远不会在 Store 中看到更新。
  • XR_KHR_loader_init_android:通过 xrGetInstanceProcAddress 并使用空实例获取 xrInitializeLoaderKHR,使用 XrLoaderInitInfoAndroidKHR 调用它,然后才能创建任何对象。
  • XR_KHR_android_create_instance:Android 专属参数通过此扩展传入 xrCreateInstance。

步骤 5 — 能通过审核的帧循环

  • 使用 xrPollEvent 驱动会话;由状态机而非布尔值决定何时开始和结束会话。
  • xrWaitFrame → xrBeginFrame → 渲染 → xrEndFrame,并根据等待返回的预测显示时间设置所有姿态。对着“现在”进行渲染,即使配置文件干净,也会产生抖动。
  • 关注焦点是 VRC 要求,而非锦上添花(VRC.Quest.Input.4):应用失去焦点时仍需继续渲染、隐藏手部和控制器,并忽略输入。在系统菜单打开时冻结的应用无法通过审核。
  • 使用 xrEnumerateSwapchainFormats 枚举交换链格式,并从返回结果中选择;硬编码格式迟早会造成兼容性问题。颜色空间必须显式指定(XR_FB_color_space),不能假定默认值。
  • 仅支持 64 位二进制文件(VRC.Quest.Packaging.6);APK 小于 1 GB,OBB 小于 4 GB (.5)。

会话状态、帧节奏和焦点规则详见:references/frame-loop.md。

步骤 6 — 检查功能,不要依赖设备型号

通过所选 SDK/运行时检查功能,而不只是判断“是不是 Quest Pro”。OpenXR 扩展枚举只是其中一层;还可能需要系统属性、权限、账户限制和有效的追踪状态。Camera2 功能不能简化为 OpenXR 扩展名称。兼容模式可能会改变报告的型号,因此仅检查设备名称并不足够。

此技能提供的后续指引

后续问题位置
可以运行,但会丢帧quest-perf(帧预算、GPU% 陷阱、捕获工具)
如何将其安装到头显/读取日志quest-tooling(metavr CLI + MCP、adb、模拟器)
如何发布quest-store(渠道、VRC、DUC、上传)
改用 WebXR 或 PWA 构建quest-webxr

让你多花一轮时间调试的注意事项

  • 开发清单通过侧载,但审核失败。 两份文档对应两套要求;发布版位于 resources/publish-mobile-manifest。
  • 启动类别错误可能看起来像渲染错误。当前 Meta 发布页面指定 com.oculus.intent.category.VR;请根据该页面和所选 SDK 检查合并后的 APK,而不是照搬通用的 OpenXR 代码片段。
  • 低于 1.0.34 的 Loader 会在启动时崩溃,且没有任何诊断信息指向 Loader。
  • hasCode="false" 与 Platform SDK 互不兼容——权益检查(VRC.Quest.Security.1,这是建议而非要求)会让原生应用引入 Java。
  • 示例是最快获得正确答案的途径。 hello_xr(Khronos)和 Meta 的 OpenXR SDK 示例——XrPassthrough、XrSceneModel、XrHandsAndControllers、XrSpaceWarp、XrSpatialAnchor、XrVirtualKeyboard——分别端到端演示一个扩展。手动编写扩展前,请先阅读示例。

以上文档信息摘自 developers.meta.com,日期为 2026-09-20;引用具体数字前,请使用 metavr docs search 重新核实。

触发词

还有一些会将请求路由到此处的短语:“Quest C++”/“Quest 用 C++”,“VR 的 AndroidManifest”/“VR 清单”,“openxr_loader_for_android”,“xrWaitFrame”,“Quest 的 targetSdk”/“Quest 的 targetSdk 是多少”,“IMMERSIVE_HMD”,“hello_xr”,“原生应用中的 passthrough”/“原生 passthrough”。

此处内容于 0.4.4 从描述中移入:“Quest 原生应用”。

评论

支持 Markdown