Develop your first immersive app
System & Services 进阶 20m

开发你的第一个沉浸式应用

Develop your first immersive app

2023年6月5日

在 Apple 官方观看视频

一句话判断

这场 Session 是空间计算平台的入门指南——从 Xcode 项目创建到 RealityView 的使用,再到 SwiftUI 手势与 RealityKit 实体的绑定,每一步都有清晰的代码示例。如果你打算做 visionOS 开发,从这里开始。

这场 Session 讲了什么

Session 系统性地介绍了在空间计算平台上开发 App 的完整流程:

项目创建: Xcode 新项目模板提供了两个关键选项:

  • Initial Scene:Window(2D 内容,平面可调,深度固定)或 Volume(3D 内容,三维尺寸由 App 控制)。
  • Immersive Space:None(不添加)、Mixed(虚拟内容叠加在透视环境上)、Progressive(约 180 度视口,用数码表冠调节)、Full(完全沉浸,隐藏透视)。

开发工具链

  • Simulator:在模拟场景中体验 App。
  • Xcode Previews:快速迭代 UI。
  • Reality Composer Pro:新工具,用于准备和预览空间内容。

核心 API

  • RealityView:SwiftUI 中嵌入 RealityKit 内容的容器。包含 make 闭包(初始化内容)和 update 闭包(响应 SwiftUI 状态变化)。
  • RealityKit Content Package:项目自动包含的内容包,由 Reality Composer Pro 管理。
  • 手势绑定:SwiftUI 手势可以精确绑定到 RealityKit 实体上(.gesture() 修饰符直接作用于三维实体)。

设计原则

  • App 应始终从 Window 开始,提供清晰的进入和退出沉浸模式的控制。
  • 不要在用户不知情的情况下强制进入沉浸模式。
  • 沉浸模式激活时,App 从 Shared Space 进入 Full Space,其他 App 被隐藏。

值得深挖的点

四种场景类型的设计层次是一个从”最小侵入”到”完全沉浸”的渐进光谱。Window 最安全,用户始终能看到周围环境;Volume 是 3D 内容的安全展示方式;Mixed Immersion 在保留环境感知的同时放置虚拟内容;Full Immersion 把用户完全带入虚拟世界。Apple 的建议是让用户自己决定何时进入哪种状态——这是对用户控制权的尊重。

RealityView 的 update 闭包不是渲染循环——这个区别至关重要。它只在 SwiftUI 状态变化时调用,不是每帧调用。如果你需要持续动画或物理模拟,应该在 RealityKit 层面处理,而不是依赖 update 闭包。

SwiftUI 手势直接绑定到 RealityKit 实体是空间交互的关键。在 2D 平台上手势作用于 View,在空间计算平台上手势可以作用于三维空间中的特定实体。这意味着你可以对不同的 3D 对象分别绑定不同的手势处理逻辑。

代码片段

RealityView 的基本结构:

import SwiftUI
import RealityKit

struct ContentView: View {
    @State private var enlarge = false

    var body: some View {
        VStack {
            // RealityView:SwiftUI 中的 3D 内容容器
            RealityView { content in
                // make 闭包:初始化 3D 内容
                if let entity = try? await ModelEntity(named: "Scene") {
                    content.add(entity)
                }
            } update: { content in
                // update 闭包:响应 SwiftUI 状态变化
                if let entity = content.entities.first {
                    entity.scale = enlarge ? SIMD3(1.5, 1.5, 1.5) : SIMD3(1, 1, 1)
                }
                // 注意:这不是渲染循环,只在状态变化时调用
            }

            // 控制按钮
            Toggle("放大", isOn: $enlarge)
                .glassBackgroundEffect()  // 玻璃背景效果,确保按钮清晰可读
        }
    }
}

SwiftUI 手势绑定到 RealityKit 实体:

RealityView { content in
    if let entity = try? await ModelEntity(named: "MyModel") {
        content.add(entity)
    }
}
.gesture(
    // 手势直接作用于 RealityKit 实体
    SpatialTapGesture()
        .targetedToAnyEntity()  // 可以精确指向特定实体
        .onEnded { value in
            // 获取被点击的三维实体
            let entity = value.entity
            // 在三维空间中执行操作
            entity.orientation = simd_quatf(angle: .pi / 4, axis: [0, 1, 0])
        }
)

最佳实践

  • App 始终从 Window 或 Volume 开始,提供明确的按钮让用户进入沉浸模式。
  • 不要自动激活 Immersive Space,让用户主动选择。
  • RealityView 的 update 闭包只用于响应 SwiftUI 状态变化,不要把它当作渲染循环。
  • 使用 Reality Composer Pro 准备 3D 内容,比纯代码创建更直观。
  • 手势使用 .targetedToAnyEntity() 可以精确绑定到被触碰的 3D 实体。
  • 在 Simulator 中测试时注意性能表现可能与真机有差异。

还有什么值得关注

  • “Meet SwiftUI for spatial computing” Session 详细介绍了 Window 场景类型。
  • “Take SwiftUI to the next dimension” Session 聚焦 Volume 场景。
  • “Go beyond the window with SwiftUI” Session 深入讲解 Immersive Space。
  • Reality Composer Pro 是全新的内容创作工具,支持预览空间内容在真实环境中的表现。
  • ARKit 的手部追踪等高级功能只在 Full Space 中可用,且需要用户授权。
WWDC 2023