VisionPro开发实践3 - ImmersiveSpace和3D手势

教程的第三篇文章拖的有点久了,以致于过年期间做了一个更精简的Demo《迎财神》,那么我就基于这个Demo来讲解一下ImmersiveSpace和3D手势吧。 可以先看一下视频: www.bilibili.com/video/BV1FK...

一、ImmersiveSpace

1.初始化

ImmersiveSpace需要一开始在初始View中就进行定义,然后通过openImmersiveSpace和dismissImmersiveSpace两个方法来进行打开和关闭。

scss 复制代码
ImmersiveSpace(id: "ImmersiveSpace") {
    ImmersiveView()
}

然后在详情View中通过"空间展示"这个按钮来进行ImmersiveSpace的展示和关闭

代码如下:

typescript 复制代码
.onChange(of: showImmersiveSpace) { _, newValue in
    Task {
        if newValue {
            switch await openImmersiveSpace(id: "ImmersiveSpace") {
            case .opened:
                immersiveSpaceIsShown = true
            case .error, .userCancelled:
                fallthrough
            @unknown default:
                immersiveSpaceIsShown = false
                showImmersiveSpace = false
            }
        } else if immersiveSpaceIsShown {
            await dismissImmersiveSpace()
            immersiveSpaceIsShown = false
        }
    }
}

2.ImmersiveSpace中的RealityView

加载模型比较简单,模型加载之后,做了三件事:

  1. 设置 旋转组件 用来让模型自动旋转
  2. 设置 输入类型 和 碰撞体积,用来支持旋转和拖拽
  3. 复制模型并放置在指定位置

接下来我会逐一讲解每一步。

二、移动与旋转手势

1. 创建Modifer

PlacementGesturesModifier是用来实现模型移动的Modifier,此代码直接Copy于官方Demo项目,不需要做修改。

DragRotationModifier是用来实现模型拖拽旋转的Modifier,此代码直接Copy于官方Demo项目。

以上两个Modifier,我会在后续的文章中继续深入讲解。

2. 在View层调用以上的Modifier

css 复制代码
ImmersiveSpace(id: "ImmersiveSpace") {
    ImmersiveView()
    .dragRotation(pitchLimit: .degrees(90))
    .placementGestures(initialPosition: Point3D([600, -600, -1800.0]))
}

在上文提到的ImmersiveView下面增加两个Modifer的调用

3. 增加模型的输入和碰撞体积

php 复制代码
scene.components[InputTargetComponent.self] = InputTargetComponent(allowedInputTypes: .all)
scene.generateCollisionShapes(recursive: true)

这两行代码非常的关键,因为如果在Reality Composer Pro中没有设置模型的输入类型和碰撞体积的,模型是无法被鼠标点击的,在真机中也无法于视线和手势交互。

基于以上三个操作,模型就可以在3D空间内被移动和拖拽旋转了。

三、自动旋转

1. 添加组件与系统

此代码依然拷贝于官方的Demo

2. 在主文件中注册组件与系统

scss 复制代码
    init() {
        RotationComponent.registerComponent()
        RotationSystem.registerSystem()
        
    }

3. 模型设置旋转系统

c 复制代码
scene.components.set(RotationComponent())

通过此行代码,保证模型可以启用RotationComponent

四、模型复制与调整位置

因为想把空间填满一些,所以粗暴的办法就是把模型复制

ini 复制代码
let upEntity = scene.clone(recursive: true)
upEntity.position.z -= 0.2
upEntity.orientation *= simd_quatf(angle: .pi, axis: [1, 0, 0])
upEntity.position.y += 2.2

let leftEntity = scene.clone(recursive: true)
leftEntity.position.x -= 0.8

let rightEntity = scene.clone(recursive: true)
rightEntity.position.x += 0.8

let downEntity = scene.clone(recursive: true)
downEntity.position.y -= 1.1

可以看到代码中,只是单纯的复制模型和移动位置。上面的模型,还做了一个沿x轴360度的旋转。

后记

终于完成了这个初级的教程,期间去了苹果实验室,在B站上认识了一个客户,帮他们顺利完成1.0版本的开发并顺利上架应用市场,苹果发售了Vision Pro,过年期间做了一个迎财神的Demo并完成了教程。

期待2024年更多的Vision Pro的应用可以落地!

相关推荐
web小白成长日记19 小时前
企业级 Vue3 + Element Plus 主题定制架构:从“能用”到“好用”的进阶之路
前端·架构
APIshop19 小时前
Python 爬虫获取 item_get_web —— 淘宝商品 SKU、详情图、券后价全流程解析
前端·爬虫·python
风送雨20 小时前
FastMCP 2.0 服务端开发教学文档(下)
服务器·前端·网络·人工智能·python·ai
XTTX11020 小时前
Vue3+Cesium教程(36)--动态设置降雨效果
前端·javascript·vue.js
LYFlied21 小时前
WebGPU与浏览器边缘智能:开启去中心化AI新纪元
前端·人工智能·大模型·去中心化·区块链
Setsuna_F_Seiei21 小时前
2025 年度总结:人生重要阶段的一年
前端·程序员·年终总结
model200521 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
han_1 天前
从一道前端面试题,谈 JS 对象存储特点和运算符执行顺序
前端·javascript·面试
aPurpleBerry1 天前
React 01 目录结构、tsx 语法
前端·react.js
jayaccc1 天前
微前端架构实战全解析
前端·架构