versionOS 学习笔记 wwdc23 Develop your first immersive app,建立第一个沉浸式虚拟现实app

699 阅读2分钟
  • 介绍如何用xcode建立 immersive App
    需要用xcode15,创建项目选择 xros

截屏2023-06-13 19.25.00.png

需要选择initail Scene和immersive Space两个选项。initail Scene有window和Volume两个选项。

window 可以理解为一个可以调整大小的平面。 Volume指一个3d形状空间,如下两个图所示。

截屏2023-06-13 19.25.54.png 截屏2023-06-13 19.26.10.png

immersive Space有Mixed、Progressive和Full。从左到右越来越沉浸。 介绍RealityView的基本使用。通过两个block 控制,初始化和更新block。RealityView本身也是SwiftUi的view,对应view用法完全都可以使用。

RealityView { content in
    // Add the initial RealityKit content
    if let scene = try? await Entity(named: "Scene", in: realityKitContentBundle) {
        content.add(scene)
    }
} update: { content in
    // Update the RealityKit content when SwiftUI state changes
    if let scene = content.entities.first {
        let uniformScale: Float = enlarge ? 1.4 : 1.0
        scene.transform.scale = [uniformScale, uniformScale, uniformScale]
    }
}
.gesture(TapGesture().targetedToEntity().onEnded { _ in
    enlarge.toggle()
})
  • 演示模拟器
    用鼠标模拟选择,可以选择不同背景,可以调节方向

image.png

  • 介绍Xcode Preview 功能 类似模拟器

  • Reality Composer Pro
    从Xcode 中可以跳入,点开Packages->点开RealityKitContent->选择Package->点右上角Open in Reality Composer Pro

image.png 下面是Reality Composer Pro操作面板,可以对立体图形进行属性调整。这里没有特别介绍怎么用代码。

image.png 另外要记住空间的坐标系,如下图 截屏2023-06-13 20.00.21.png
调整对应对象需要按照这个来。

  • 相关代码演示
    这个部分苹果工程师讲解了一些入门的代码,如建立沉浸式场景
@main
struct MyFirstImmersiveApp: App {
   var body: some Scene {
       WindowGroup {
           ContentView()
       }.windowStyle(.volumetric)

       ImmersiveSpace(id: "ImmersiveSpace") {
           ImmersiveView()
       }
   }
}

打开沉浸式空间

struct ContentView: View {

    @Environment(.openImmersiveSpace) var openImmersiveSpace

    var body: some View {
        Button("Open") {
            Task {
                await openImmersiveSpace(id: "ImmersiveSpace")
            }
        }
    }
}

加上点击效果

import SwiftUI
import RealityKit

struct ContentView: View {
    var body: some View {
        RealityView { content in
            // For entity targeting to work, entities must have a CollisionComponent
            // and an InputTargetComponent!
        }
        .gesture(TapGesture().targetedToAnyEntity().onEnded { value in
            print("Tapped entity (value.entity)!")
        })
    }
}

补充动画效果

.gesture(TapGesture().targetedToAnyEntity().onEnded { value in
    var transform = value.entity.transform
    transform.translation += SIMD3(0.1, 0, -0.1)
    value.entity.move(
        to: transform,
        relativeTo: nil,
        duration: 3,
        timingFunction: .easeInOut
    )
})

源链接 developer.apple.com/videos/play…