VisionPro开发实践1 - 创建一个3D模型列表

一、创建项目

我这里用的是Xcode15-beta8, 模拟器用的是visionOS_1_beta_3

  1. 通过Xcode -> File -> New -> Project来创建项目
  1. 选择visionOS这个tab 然后选择 下面的App
  1. 进一步选择一下初始的模板

这里 Inital Scene 选择Window,Immersive Space Render选择RealityKit,Immersive Space选择Mixed。

二、创建列表视图

我们可以看到一开始的模板代码和Preview的效果

php 复制代码
        VStack {
            Model3D(named: "Scene", bundle: realityKitContentBundle)
                .padding(.bottom, 50)

            Text("Hello, world!")

            Toggle("Show Immersive Space", isOn: $showImmersiveSpace)
                .toggleStyle(.button)
                .padding(.top, 50)
        }
        .padding()
        .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
                }
            }
        }

添加3D模型资源

双击打开Packages -> RealityKitContent -> Package, 然后再点击右上角的Open in Reality Composer Pro

然后把之前生成好的 usdz文件拖进来就可以了。

编写列表视图代码

我们可以继续保留模板,但是把View中的内容替换成我们要去创建的视图。

代码如下:

scss 复制代码
NavigationSplitView {
    List(0..<30, id: .self, selection: self.$selection) { i in
        HStack(alignment: .top) {
            Model3D(named: "Speedy", bundle: realityKitContentBundle)
            Text("ID: (i)")
            Text("路易威登 NeoNoe背包")
        }
    }
} detail: {
    ItemDetailView()
}

这里通过一个NavigationSplitView来包裹一个List视图,List中的每一个列表项由三部分组成:

  1. 3D模型

  2. ID文本

  3. 标题文本

这里使用Model3D来加载3D模型,通过named参数跟刚刚在 Reality Composer Pro中导入的模型进行关联。

但是当我以这样的方式展示时,发现3D模型按照他原有的尺寸展示太大了,把文本都挤出去了,这个时候我就想到了需要进行缩放。

3D模型缩放

我这里用到的缩放方式是:

less 复制代码
Model3D(named: "Speedy", bundle: realityKitContentBundle)
    .scaleEffect(x: 0.1, y: 0.1, z: 0.1)

这个时候会发现,3D模型是已经缩放了,但是还是占据了过大的空间,导致列表中无法显示其他内容。所以这里需要设定3D模型视图的框架尺寸。

设置3D模型框架的尺寸

less 复制代码
Model3D(named: "Speedy", bundle: realityKitContentBundle)
    .frame(width: 10, height: 10)
    .scaleEffect(x: 0.1, y: 0.1, z: 0.1)

这个时候发现,尺寸是正确了,整个列表的空间也正常了。 但是,这个3D模型怎么漂浮在空中呢?经过查资料之后,发现Model3D还可以通过设置一个depth的维度,来控制其Z轴的尺寸。

less 复制代码
Model3D(named: "Speedy", bundle: realityKitContentBundle)
    .frame(depth: 1, alignment: .center)
    .frame(width: 10, height: 10)
    .scaleEffect(x: 0.1, y: 0.1, z: 0.1)
    .padding(.init(top: 0, leading: 10, bottom: 0, trailing: 10))

通过以上代码,再加上padding,这个列表的布局基本OK了

但是这里还有一个很奇葩的问题,就是我的3D模型太暗了

左边是原始模型,右边是渲染后的模型,应该是跟光线相关的设置。结果网上找了一圈资料没找到相关信息,用模拟器跑起来就好了。。看来是Preview的问题。

到这里,基础的列表展示就完成了。后续实践将进行详情视图的编写,以及Immersive视图的编写。

参考文章

stackoverflow.com/questions/7...

www.fatbobman.com/posts/new_n...

stackoverflow.com/questions/7...

相关推荐
前端爆冲8 分钟前
项目中无用export的检测方案
前端
热爱编程的小曾36 分钟前
sqli-labs靶场 less 8
前端·数据库·less
gongzemin1 小时前
React 和 Vue3 在事件传递的区别
前端·vue.js·react.js
Apifox1 小时前
如何在 Apifox 中通过 Runner 运行包含云端数据库连接配置的测试场景
前端·后端·ci/cd
树上有只程序猿1 小时前
后端思维之高并发处理方案
前端
鸿蒙布道师2 小时前
鸿蒙NEXT开发对象工具类(TS)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
庸俗今天不摸鱼2 小时前
【万字总结】前端全方位性能优化指南(十)——自适应优化系统、遗传算法调参、Service Worker智能降级方案
前端·性能优化·webassembly
黄毛火烧雪下2 小时前
React Context API 用于在组件树中共享全局状态
前端·javascript·react.js
Apifox2 小时前
如何在 Apifox 中通过 CLI 运行包含云端数据库连接配置的测试场景
前端·后端·程序员
一张假钞2 小时前
Firefox默认在新标签页打开收藏栏链接
前端·firefox