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

细心的读者会发现在在​​Day1​​​和​​Day2​​​的示例中我们使用的都是​​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开发学习笔记​

相关推荐
missmisslulu7 小时前
电容笔值得买吗?2024精选盘点推荐五大惊艳平替电容笔!
学习·ios·电脑·平板
GEEKVIP8 小时前
手机使用技巧:8 个 Android 锁屏移除工具 [解锁 Android]
android·macos·ios·智能手机·电脑·手机·iphone
GEEKVIP8 小时前
如何在 Windows 10 上恢复未保存/删除的 Word 文档
macos·ios·智能手机·电脑·word·笔记本电脑·iphone
奇客软件9 小时前
iPhone使用技巧:如何恢复变砖的 iPhone 或 iPad
数码相机·macos·ios·电脑·笔记本电脑·iphone·ipad
奇客软件1 天前
如何从相机的记忆棒(存储卡)中恢复丢失照片
深度学习·数码相机·ios·智能手机·电脑·笔记本电脑·iphone
GEEKVIP2 天前
如何修复变砖的手机并恢复丢失的数据
macos·ios·智能手机·word·手机·笔记本电脑·iphone
一丝晨光2 天前
继承、Lambda、Objective-C和Swift
开发语言·macos·ios·objective-c·swift·继承·lambda
GEEKVIP2 天前
iPhone/iPad技巧:如何解锁锁定的 iPhone 或 iPad
windows·macos·ios·智能手机·笔记本电脑·iphone·ipad
KWMax2 天前
RxSwift系列(二)操作符
ios·swift·rxswift