mcpField
H
hz-spatial-sdk

hz-spatial-sdk

github.com/meta-quest开发241193 次安装5 周前更新
代码仓库

关于 hz-spatial-sdk

指导开发者使用 Meta Spatial SDK 和 Kotlin 构建 Horizon OS 原生 Android 空间应用。内容涵盖 ECS、空间 UI 面板、3D 内容、混合体验以及部署到 Meta VR 设备。

主要功能

  1. 01使用 Kotlin 构建原生 Android 空间应用
  2. 02通过 ECS 管理场景实体
  3. 03将 Compose 或 Android Views 渲染为空间面板
  4. 04加载并放置 glTF 模型
  5. 05组合 2D 面板与 3D 内容
  6. 06构建并部署到 Meta VR 设备

适用场景

  1. 01开发带空间界面的 Android 应用
  2. 02创建包含 2D 界面与 3D 模型的混合体验
  3. 03用 ECS 实现 3D 场景逻辑
  4. 04在设备上安装并测试空间应用

安装

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

$npx skills add https://github.com/meta-quest/agentic-tools --skill hz-spatial-sdk

安装后在 Claude Code 中输入/hz-spatial-sdk确认已加载。

包含的文件

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

references/
architecture-guide.md
debugging.md
interaction-sdk.md
panels-and-3d.md

详细介绍

Spatial SDK 技能

使用 Meta Spatial SDK 为 Meta VR 构建原生 Android 空间应用。本技能涵盖实体-组件-系统架构、2D 面板渲染、3D 对象放置、混合应用开发,以及向 Horizon OS 设备部署。

何时使用本技能

在以下情况下使用本技能:

  • 使用 Spatial SDK 和 Kotlin 为 Meta VR 构建原生 Android 应用
  • 创建结合 2D Android UI 面板与 3D 内容的混合体验
  • 使用 Spatial SDK 的实体-组件-系统(ECS)架构
  • 为 Meta VR 应用添加 3D 对象、动画或空间交互
  • 使用 Jetpack Compose 或 Android Views 配置面板以进行空间渲染
  • 使用 Spatial Editor 以可视化方式构建 3D 场景
  • 在 Meta VR 设备上部署和测试 Spatial SDK 应用

本技能适用于运行 Horizon OS 的所有 Meta Quest 头显(Quest 2、Quest 3、Quest 3S、Quest Pro)。

什么是 Meta Spatial SDK

Meta Spatial SDK 是 Meta 为在 Horizon OS 上构建空间应用而提供的原生 Android 框架。它通过加入空间能力扩展了标准 Android 开发模式,让开发者可以使用 Kotlin 编写应用,在 3D 空间中渲染 2D UI 面板、显示 glTF 模型、处理空间输入,并集成透视、场景理解和手部追踪等 Horizon OS 功能。

与 Unity 或 Unreal Engine 不同,Spatial SDK 基于 Android Activity 生命周期构建。应用是标准的 Android APK,通过使用 Spatial SDK 库来获得空间渲染和交互能力。

主要特点:
  • Kotlin 优先:所有应用逻辑均使用 Kotlin 编写
  • 原生 Android:基于标准 Android Activity、Gradle 和 Jetpack 库构建
  • ECS 架构:通过实体、组件和系统管理 3D 场景状态
  • 面板渲染:Android UI 框架(Jetpack Compose、Views)以空间面板的形式渲染
  • Gradle 集成:Spatial SDK 以 AAR 库形式提供,通过 Gradle 依赖引入

核心概念

实体-组件-系统(ECS)

Spatial SDK 使用 ECS 架构管理 3D 场景图,将数据(组件)与行为(系统)分离:

  • 实体:用于组合组件的轻量级标识符(ID)。实体本身不包含任何行为。
  • 组件:附加到实体上的数据容器。组件通过 XML 属性架构定义,并包含类型化字段(浮点数、向量、引用、枚举)。例如:Transform、Mesh、Panel、Grabbable。
  • 系统:按组件查询实体并逐帧执行逻辑的 Kotlin 类。系统继承 SystemBase 并重写 execute() 方法。
// Example: a simple system that rotates all entities with a Spinner component
class SpinnerSystem : SystemBase() {
  private var previousTime = 0L

  override fun execute() {
    val currentTime = System.currentTimeMillis()
    if (previousTime == 0L) previousTime = currentTime
    val timeDeltaInSeconds = (currentTime - previousTime) / 1000f
    previousTime = currentTime

    val query = Query.where { has(Spinner.id, Transform.id) }
    for (entity in query.eval()) {
      val transform = entity.getComponent<Transform>()
      val spinner = entity.getComponent<Spinner>()
      transform.transform.q =
        transform.transform.q * Quaternion(0f, spinner.speed * timeDeltaInSeconds, 0f)
      entity.setComponent(transform)
    }
  }
}
2D 面板

面板是空间应用中显示 Android UI 的主要方式。类型化的 PanelRegistration 将整数资源 ID 映射到 Jetpack Compose 组合项、 Android View、Activity 或媒体表面。面板会渲染为放置在 3D 场景中的 表面。

override fun registerPanels(): List<PanelRegistration> {
  return listOf(
    ComposeViewPanelRegistration(
      registrationId = R.id.main_panel,
      composeViewCreator = { _, context ->
        ComposeView(context).apply { setContent { MainScreen() } }
      },
      settingsCreator = {
        UIPanelSettings(
          shape = QuadShapeOptions(width = 0.8f, height = 0.6f),
          display = DpDisplayOptions(width = 592f, height = 444f),
        )
      },
    )
  )
}
3D 对象

将 glTF 模型作为网格加载,并使用 Transform 和 Mesh 组件将其放置在场景中:

val modelEntity = Entity.create()
modelEntity.setComponent(
  Mesh(Uri.parse("apk:///models/robot.glb"))
)
modelEntity.setComponent(
  Transform(Pose(Vector3(0f, 1f, 2f)))
)
混合应用

Spatial SDK 擅长构建将 2D 面板与 3D 内容相结合的混合应用。单个 Activity 可以同时显示 Android UI 面板和 3D 模型,让用户在空间内容环绕下与熟悉的 2D 界面交互。

Activity 结构

对于大多数 Spatial SDK 应用,请将一个 AppSystemActivity 子类作为整个体验的根容器。工具类应用通常最适合由这一个 Activity 管理场景、已注册面板和 ECS 系统,并在该容器中切换 UI 状态。

除非有特定的平台原因,否则避免将面向 Quest 原生平台的工具应用构建成标准的多 Activity Android 应用。通常,在同一个空间 Activity 中实现多个面板或不同 UI 状态会更合适。

Scene

Scene 类用于管理 3D 环境,包括天空盒、基于图像的光照(IBL)、视图原点和参考空间。每个 AppSystemActivity 都关联一个场景。

Spatial Editor

Spatial Editor 是一种可视化工具(通过 Meta Horizon 插件集成到 Android Studio),用于编辑 3D 场景。它会生成 .glxf 文件,用于定义实体布局、面板位置和 3D 对象位置。这些文件会在运行时加载。

快速入门

先决条件
  1. Android Studio,并已安装 Meta Horizon Android Studio Plugin
  2. Meta Spatial SDK 依赖项已添加到 Gradle 项目
  3. Meta VR 设备已通过 USB 连接,并启用了开发者模式
分步指南
  1. 在 Android Studio 中使用 Spatial SDK 模板创建新项目(或将 Spatial SDK 依赖项添加到现有项目)。

  2. 定义 activity:扩展 AppSystemActivity,并使用当前的类型化面板注册 API:

class MyActivity : AppSystemActivity() {

  override fun registerPanels(): List<PanelRegistration> {
    return listOf(
      ComposeViewPanelRegistration(
        registrationId = R.id.home_panel,
        composeViewCreator = { _, context ->
          ComposeView(context).apply { setContent { HomeScreen() } }
        },
        settingsCreator = {
          UIPanelSettings(
            shape = QuadShapeOptions(width = 0.8f, height = 0.6f),
            display = DpDisplayOptions(width = 592f, height = 444f),
          )
        },
      )
    )
  }

  override fun registerFeatures(): List<SpatialFeature> {
    return listOf(VRFeature(this), ComposeFeature())
  }

  override fun onSceneReady() {
    super.onSceneReady()
    scene.setReferenceSpace(ReferenceSpace.LOCAL_FLOOR)
    Entity.create(
      Panel(panelRegistrationId = R.id.home_panel),
      Transform(Pose(Vector3(0f, 1.2f, 2f))),
      Visible(true),
    )
  }
}
  1. 通过 Spatial Editor 或以编程方式添加 3D 内容:
// Load a 3D model
val robot = Entity.create(
  Mesh(Uri.parse("apk:///models/robot.glb")),
  Transform(Pose(Vector3(0f, 0.5f, 1.5f)))
)
  1. 使用 metavr 构建并部署到已连接的 Meta VR 设备(通过 metavr <args> 调用;如果 metavr 不在 PATH 中,则使用 npx -y metavr <args>):
# Build the APK via Gradle
./gradlew assembleDebug

# Install using metavr
metavr app install app/build/outputs/apk/debug/app-debug.apk

# Launch the app
metavr app launch com.example.myspatialapp

# View logs
metavr log

架构概览

Spatial SDK 应用的高层架构:

Android Activity
  └── AppSystemActivity
        ├── Scene (environment, lighting, viewer)
        ├── DataModel (entity-component store)
        │     ├── Entity: Panel (R.id.home_panel)
        │     │     ├── Transform
        │     │     ├── PanelComponent
        │     │     └── Grabbable
        │     ├── Entity: 3D Object ("robot")
        │     │     ├── Transform
        │     │     └── Mesh
        │     └── Entity: Light
        │           ├── Transform
        │           └── PointLight
        ├── Features
        │     ├── VRFeature (includes ISDK input by default)
        │     └── PhysicsFeature
        ├── Systems
        │     └── SpinnerSystem
        └── PanelRegistrations
              └── R.id.home_panel → Jetpack Compose UI
  • AppSystemActivity 扩展 Android Activity,并管理 Scene 和 DataModel 的生命周期。
  • DataModel 是中心化的 ECS 存储,所有实体和组件都位于其中。
  • Scene 用于配置 3D 环境(天空盒、IBL、参考空间)。
  • Systems 每帧运行一次,并对符合其查询条件的实体进行操作。
  • PanelRegistrations 将稳定的整数资源 ID 绑定到 UI 内容。

Gradle 依赖项

将当前官方模板中的 Spatial SDK 别名复制到项目的版本目录中。在使用时解析最新稳定版本,并确保插件和每个模块使用相同的 spatialsdk 版本:

# gradle/libs.versions.toml
[versions]
spatialsdk = "<latest-stable-version>"

[libraries]
meta-spatial-sdk-base = { module = "com.meta.spatial:meta-spatial-sdk", version.ref = "spatialsdk" }
meta-spatial-sdk-toolkit = { module = "com.meta.spatial:meta-spatial-sdk-toolkit", version.ref = "spatialsdk" }
meta-spatial-sdk-vr = { module = "com.meta.spatial:meta-spatial-sdk-vr", version.ref = "spatialsdk" }
meta-spatial-sdk-compose = { module = "com.meta.spatial:meta-spatial-sdk-compose", version.ref = "spatialsdk" }

[plugins]
meta-spatial-plugin = { id = "com.meta.spatial.plugin", version.ref = "spatialsdk" }

在 app 模块中使用这些别名:

plugins {
  alias(libs.plugins.meta.spatial.plugin)
}

dependencies {
  implementation(libs.meta.spatial.sdk.base)
  implementation(libs.meta.spatial.sdk.toolkit)
  implementation(libs.meta.spatial.sdk.vr)
  implementation(libs.meta.spatial.sdk.compose)
}

仅在应用使用 meta-spatial-sdk-isdk、meta-spatial-sdk-physics、meta-spatial-sdk-mruk 或 meta-spatial-sdk-spatialaudio 等可选模块时才添加它们,并在 libs.versions.toml 中引用相同的 spatialsdk 版本。

Manifest 配置

Spatial SDK 应用需要特定的 manifest 条目:

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


<uses-feature
  android:name="oculus.software.handtracking"
  android:required="false" />
<uses-permission android:name="com.oculus.permission.HAND_TRACKING" />

<application>
  <activity
    android:name=".MyActivity"
    android:exported="true">
    <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>
  </activity>
</application>

对于无需控制器也应能运行的面板或混合应用,请声明手部追踪支持,并确保体验能够顺畅处理手部与控制器之间的切换。Meta 的 VRC 指南同样适用于面板应用和沉浸式应用。

如果应用需要通过 http:// 或 ws:// 与本地开发服务通信,可能还需要仅用于调试的明文流量设置或网络安全配置。请将这些配置限定在开发构建中,并优先在发布构建中使用 https:// 和 wss://。

参考资料

技能参考资料
  • 架构指南 -- ECS 模型、自定义组件和系统、场景管理以及 activity 生命周期
  • 面板和 3D 对象 -- 2D 面板渲染、3D 对象加载、混合应用开发
  • Interaction SDK -- 输入处理、可抓取对象、手部追踪、控制器输入、触觉反馈
  • 调试 -- Data Model Inspector、OVR Metrics Tool、logcat 过滤、常见问题

评论

支持 Markdown