visionOS空间计算实战开发教程Day 4 初识ImmersiveSpace

简介: 沉浸式空间为内容提供了一个无界的区域,可在空间内控制内容的大小和摆放位置。在获取用户的授权后,我们还可以使用开启了沉浸空间的ARKit来将内容集成到周遭环境中。例如,可以使用ARKit场景重建来获取家具的网格(mesh)及其附近的对象,让内容可以与网格进行交互。

细心的读者会发现在在Day1Day2的示例中我们使用的都是WindowGroup

@main
struct visionOSDemoApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

本节我们来认识在visionOS开发中会经常用到的另一个概念ImmersiveSpace

沉浸式空间为内容提供了一个无界的区域,可在空间内控制内容的大小和摆放位置。在获取用户的授权后,我们还可以使用开启了沉浸空间的ARKit来将内容集成到周遭环境中。例如,可以使用ARKit场景重建来获取家具的网格(mesh)及其附近的对象,让内容可以与网格进行交互。

首先我们需要创建一个ViewModel.swift文件用于进行内容的相关配置。

import SwiftUI
import RealityKit
import ARKit
@MainActor class ViewModel: ObservableObject {
    private let session = ARKitSession()
    private let worldTracking = WorldTrackingProvider()
    private var contentEntity = Entity()
    func setupContentEntity() -> Entity {
        let box = ModelEntity(mesh: .generateBox(width: 0.5, height: 0.5, depth: 0.5))
        contentEntity.addChild(box)
        return contentEntity
    }
    func runSession() async {
        print("WorldTrackingProvider.isSupported: \(WorldTrackingProvider.isSupported)")
        print("PlaneDetectionProvider.isSupported: \(PlaneDetectionProvider.isSupported)")
        print("SceneReconstructionProvider.isSupported: \(SceneReconstructionProvider.isSupported)")
        print("HandTrackingProvider.isSupported: \(HandTrackingProvider.isSupported)")
        Task {
            let authorizationResult = await session.requestAuthorization(for: [.worldSensing])
            for (authorizationType, authorizationStatus) in authorizationResult {
                print("Authorization status for \(authorizationType): \(authorizationStatus)")
                switch authorizationStatus {
                case .allowed:
                    break
                case .denied:
                    // TODO
                    break
                case .notDetermined:
                    break
                @unknown default:
                    break
                }
            }
        }
        Task {
            try await session.run([worldTracking])
            for await update in worldTracking.anchorUpdates {
                switch update.event {
                case .added, .updated:
                    print("Anchor position updated.")
                case .removed:
                    print("Anchor position now unknown.")
                }
            }
        }
    }
}

setupContentEntity方法中,我们通过ModelEntity创建了一个模型实体,其中对mesh参数使用MeshResource.generateBox创建了一个立方体,可使用参数的说明如下:

  • mesh: 定义模型几何形状的网格。
  • materials: 定义模型外观的材质资源。
  • collisionShape: 定义合成碰撞开关的形状资源集合。
  • mass: 按公斤计的模型质量。

另一个异步方法runSession用于进行配置和授权的处理,其中包含两个Task

通常我们会创建一个ImmersiveView来显示沉浸空间的效果,但本例我们都放到了入口文件中:

import SwiftUI
import RealityKit
@main
struct visionOSDemoApp: App {
    @StateObject var model = ViewModel()
    var body: some SwiftUI.Scene {
        ImmersiveSpace {
            RealityView { content in
                content.add(model.setupContentEntity())
            }
            .task{
                await model.runSession()
            }
        }
    }
}

注意因为这里导入了RealityKit,所以为避免歧义我们使用了SwiftUI.Scene,然后在主体内容中是一个RealityView,其中添加了我们在ViewModel中所创建的立方体,同时使用异步任务去执行授权部分的runSession()方法。

代码部分就是这么多,但在运行应用前我们还要配置一下Info.plist文件,我们需要将Preferred Default Scene Session Role选项修改为Immersive Space Application Session Role

这时运行应用就会看到本文前面显示的效果,最后我们再来了解一个调试的工具,在代码区下方点击图标即可打开Visualizations弹窗,通过显示检测到表面、遮挡和锚点等来辅助我们的开始,我们的示例图片便是勾选了Surfaces之后的效果。

示例代码:GitHub仓库

其它相关内容请见虚拟现实(VR)/增强现实(AR)&visionOS开发学习笔记

相关文章
|
存储 运维 网络协议
ISCSI详解(二)——ISCSI基础知识
ISCSI详解(二)——ISCSI基础知识
420 4
|
2月前
|
人工智能 安全 Linux
喂饭级教学:OpenClaw全平台部署(阿里云/Win11/MacOS/Linux)+百炼Coding Plan配置+16款必装Skill+FAQ
“用OpenClaw却只当聊天机器人?你可能浪费了它90%的潜力”——这是2026年无数“小龙虾养殖户”(OpenClaw用户昵称)的共同顿悟。作为GitHub星标突破30万的开源AI框架,OpenClaw的真正威力藏在Skill(插件)生态中:从语音转文字、PDF编辑,到股市分析、知识库联动,16款高价值插件能让它从“被动应答工具”进化为“主动解决问题的全能助手”。
1020 3
|
4月前
|
JSON C# 数据格式
C# 实现简单的 HTTP 请求工具(POST 补充)
该代码实现了一个基于 HttpClient 的异步 HTTP POST 请求工具类,支持以 JSON 格式提交数据并反序列化响应结果,具备异常处理机制,适用于 .NET 环境下的轻量级网络请求操作。
|
6月前
|
机器学习/深度学习 人工智能 算法
乘AIGC浪潮:把握万亿级机遇
AIGC正加速从技术走向产业落地,万亿市场规模催生全链条人才需求。北京、上海政策加码,算力基建完善,2025-2027年成关键窗口期。七大核心岗位——AIGC工程师、大模型训练师、AI工程师等全面爆发,覆盖技术到应用各层级,高薪抢人成常态。工信部认证加持,职业前景广阔,人人皆可入局,抢占AI时代新风口。
608 1
|
Swift 索引
Swift开发——元组
Swift中的元组是一种数据结构,用于组合不同类型的值。它们不是独立的数据类型,而是以有序序列形式存在,用圆括号括起,元素间用逗号分隔。元组可以有任意数量和类型的元素,可变性取决于其定义。常用于函数返回多个值。示例代码展示了元组的创建、访问、解包及赋值。元组可以通过标签来标识元素,支持嵌套和比较。在函数返回值和并行赋值场景中,元组特别有用。
440 0
Swift开发——元组
|
存储 SQL 关系型数据库
使用关系型数据库三级模式存储数据的优缺点
【6月更文挑战第10天】数据模型是DBMS的核心,提供数据透明性和设计指导。包括概念、逻辑和物理三层:概念模型(如ER模型)用于理解和收集需求,逻辑模型(如关系模型)关注设计,物理模型涉及实际存储实现。
544 0
使用关系型数据库三级模式存储数据的优缺点
|
SQL 存储 分布式计算
Spark 3.0 对于 DATE 和 TIMESTAMP 的改进
本文将会深入介绍DATE和TIMESTAMP
Spark 3.0 对于 DATE 和 TIMESTAMP 的改进
|
机器学习/深度学习 人工智能 PyTorch
Transformers 4.37 中文文档(三十二)(1)
Transformers 4.37 中文文档(三十二)
468 0
|
API
uView route 路由跳转
uView route 路由跳转
341 0
|
算法
判断单链表是否有环?中点如何判断?入环点如何判断?
判断单链表是否有环?中点如何判断?入环点如何判断?
544 0