WWDC Quick Look 💓 By SwiftGGTeam
Build great games for spatial computing

Build great games for spatial computing

观看原视频

Highlight

visionOS supports games across a full spectrum of immersion — from 2D windows in the Shared Space to fully immersive experiences — with RealityKit, Unity, Metal, and standard game controllers all available as development paths.

核心内容

你做过 iOS 游戏,也许还做过 VR 游戏。visionOS 提供了介于两者之间的可能性:你的游戏可以是一个悬浮在桌面上的棋盘,可以是占据整个房间的动作游戏,也可以是完全替代现实的沉浸式世界。选择哪种形态,取决于你想捕获玩家多少注意力。

四种沉浸等级

所有应用和游戏都从 Shared Space 开始。在这个模式下,你的游戏与其他应用、系统 UI 和真实环境共存。虚拟棋盘放在真实桌面上,虚拟宠物坐在真实地板上。玩家可以自由选择交互对象。

01:45)进入 Full Space 后,其他窗口和体积都被关闭,焦点完全集中在你的内容上。但玩家仍通过穿透(passthrough)看到周围环境。这适合动作游戏——比如飞船从墙上的洞里飞出来。

02:08)Fully Immersive 体验完全替代玩家的视野,真实世界消失,取而代之的是一个虚拟环境。这是传统 VR 的体验模式。

02:18)传统 2D 游戏也在 visionOS 上运行。玩家可以把窗口放到桌面、挂到墙上、或放到眼前作为巨幕。窗口有真实的深度,可以渲染分层内容获得视差效果,也可以让元素(如烟雾、火花)飞出平面。

渲染特性

visionOS 的渲染与传统平台不同。你不渲染每个像素,而是描述场景(模型、纹理、着色器),设备自动为每只眼睛渲染。

04:36)系统会自动应用动态注视点渲染(dynamic foveation),在玩家注视区域使用更高分辨率,无需开发者干预。

05:07)RealityKit 默认采样真实房间的光照,应用到虚拟物体上,获得真实感。你也可以偏离这条路线,使用自定义 IBL 或 MaterialX 着色器创造奇幻风格。

05:55)系统会自动应用几个全系统效果:深度缓解(内容被真实物体遮挡时变透明)、近场暗角(内容太近时淡出)、突破(真人走近时穿透虚拟内容)、地面阴影(虚拟物体靠近真实物体时投射阴影)。

音频

07:57)visionOS 使用 Spatial Audio 让声音在玩家空间中定位。使用标准 iOS 音频 API(如 AVAudioEngine)时,音频相对于应用窗口定位。如果希望声音来自场景中的不同物体,需要通过 RealityKit 在特定实体上播放音频。

输入方式

08:52)系统提供注视+手指轻触的标准手势。要让手势在 3D 物体上工作,物体需要同时具备 CollisionComponent(提供碰撞形状)和 InputTargetComponent(标记为可交互)。

09:19)visionOS 支持蓝牙游戏手柄、键盘、鼠标和触控板。对于需要快速或并发输入的游戏,手柄是更好的选择。在 Info.plist 中声明 GCSupportsControllerUserInteraction 并添加 Game Controller capability。

09:53)更非常规的输入方式包括身体追踪。通过 ARKit 获取手部追踪数据,让玩家抓取虚拟物体或实现自定义手势(如指向、空手劈)。需要注意:手只有在摄像头视野内才能被追踪,快速运动难以追踪。

场景理解

10:25)在 Full Space 中可以请求场景理解,获得房间虚拟网格、平面检测(水平和垂直表面)、以及表面材质(地毯或木头)。这让房间本身成为游戏输入的一部分。和手部追踪一样,需要用户授权。

开发框架选择

12:15)根据游戏类型选择框架:

  • 2D 游戏:SwiftUI 或 SpriteKit
  • 已有 Unity 游戏:Unity 支持 visionOS,可访问穿透、高分辨率渲染和原生手势
  • 原生 3D 游戏:RealityKit,支持 ECS、物理、动画、粒子和音频
  • 自研引擎:CompositorServices API + Metal + ARKit

14:38)visionOS 的 Xcode 模板给你一个带 RealityView 的 SwiftUI 窗口。要跳出窗口,可以使用 Volume(你指定尺寸,玩家放置位置)或 Space(在玩家周围渲染内容)。Anchor 可以将内容锚定到真实世界的表面或手部。Portal 可以在墙上”打洞”,展示内部的虚拟世界。

详细内容

让 3D 物体响应手势输入

要使系统手势在 RealityKit 实体上工作,需要添加两个组件:

// 创建一个可交互的 3D 物体
let entity = Entity(named: "game_piece")

// 提供碰撞形状——手势检测的基础
entity.components.set(CollisionComponent(shapes: [.generateSphere(radius: 0.1)]))

// 标记为可交互目标
entity.components.set(InputTargetComponent())

关键点:

  • CollisionComponent 定义了手势检测的物理边界
  • InputTargetComponent 告诉系统这个实体可以接收输入事件
  • 没有这两个组件,注视+轻触手势不会在该物体上触发
  • 碰撞形状可以与视觉模型不同——可以用更简单的几何体优化性能

声明游戏手柄支持

在 Info.plist 中添加:

<key>GCSupportsControllerUserInteraction</key>
<true/>

并在 Xcode 的 Signing & Capabilities 中添加 Game Controller capability。

关键点:

  • 声明后 App Store 产品页会显示控制器支持徽章
  • visionOS 支持 Xbox、PlayStation 和其他 MFi 控制器
  • 蓝牙键盘和鼠标也受支持
  • 玩家可以通过穿透看到手中的物理控制器

请求场景理解

import ARKit

// 在 Full Space 中请求场景理解
let session = ARKitSession()
let planeDetection = PlaneDetectionProvider(alignments: [.horizontal, .vertical])
let sceneReconstruction = SceneReconstructionProvider()

try await session.run([planeDetection, sceneReconstruction])

// 处理检测到的平面
for await update in planeDetection.anchorUpdates {
    switch update.event {
    case .added, .updated:
        let plane = update.anchor
        // 使用 plane.originFromAnchorTransform 获取位置
        // 使用 plane.extent 获取平面尺寸
    case .removed:
        break
    }
}

关键点:

  • 场景理解只在 Full Space 中可用
  • 需要用户授权,与位置/麦克风权限类似
  • PlaneDetectionProvider 检测水平和垂直表面
  • SceneReconstructionProvider 提供房间网格
  • 可以获取表面材质信息(如 carpet、wood)

使用 Volume 展示 3D 内容

与 Window 不同,Volume 的尺寸由开发者指定,玩家只能改变位置不能改变大小:

@main
struct MyGameApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .windowStyle(.volumetric)  // 使用体积窗口样式
        .defaultSize(width: 1.5, height: 1.0, depth: 1.0, in: .meters)
    }
}

关键点:

  • .windowStyle(.volumetric) 将窗口变为体积
  • .defaultSize 指定体积的宽、高、深(单位:米)
  • 内容不会超出体积边界被裁剪
  • 玩家可以拖动体积到任意位置,但尺寸固定

核心启发

1. 设计一个桌面棋盘游戏

利用 Shared Space 的特性,设计一个虚拟棋盘游戏,棋盘放在真实桌面上,棋子有 3D 深度。玩家用注视+轻触移动棋子,也可以用蓝牙手柄加速操作。入口:RealityKit + CollisionComponent/InputTargetComponent + SwiftUI 窗口。

2. 创建一个房间尺度的动作游戏

使用 Full Space + 场景理解,让游戏内容与现实房间互动。敌人从真实墙壁后面出现,玩家需要躲避真实家具。入口:ARKit 的 SceneReconstructionProvider + PlaneDetectionProvider,结合 RealityKit 的实体放置。

3. 为现有 iOS 游戏添加 3D 元素

如果你的游戏已经是 2D(如解谜、卡牌、策略),不需要重写。在 SwiftUI 窗口中添加 RealityKit 体积内容——比如卡牌打出时有 3D 动画效果,或者游戏场景有视差深度。入口:在现有 SwiftUI 视图中嵌入 RealityView

4. 实现手势控制的体感游戏

使用 ARKit 手部追踪实现自定义手势作为游戏输入。比如空手劈砍游戏——玩家用手势劈开飞来的物体。入口:HandTrackingProvider + 自定义手势识别逻辑 + CollisionComponent 检测碰撞。

关联 Session

评论

GitHub Issues · utterances