除了可以放入3D模型在空間之內,也可以用自動生成的方式,產生3D模型出來。
首先先匯入ARKit:
import ARKit
然後新增一個class,這個class就是用來產生模型的class:
@MainActor class Day4ViewModel: ObservableObject {
private var contentEntity = Entity()
func setupContentEntity() -> Entity {
let box = ModelEntity(mesh: .generateBox(width: 0.5, height: 0.5, depth: 0.5))
box.position = SIMD3(x: 10, y: 0, z: -4)
contentEntity.addChild(box)
return contentEntity
}
}
@MainActor是表示這個class的所有方法和屬性都會在主執行緒上執行,因為在SwiftUI上的UI更新必須在主執行緒上執行。
ObservableObject表示當屬性發生變化時,將會自動更新。
Entity是一個基本的容器,可以用來產生AR內容,如模型、光源和其它實體。
let box = ModelEntity(mesh: .generateBox(width: 0.5, height: 0.5, depth: 0.5))
創建了一個3D立方體模型,並且根據寬度、高度和深度來產生出一個立方體出來。
box.position = SIMD3(x: 10, y: 0, z: -4)
設置了立方體的空間位置。SIMD3是一個三維向量,用於宣告立方體在x、y、z軸上的位置。這裡將立方體放置在x軸10單位,y軸0 單位,z軸-4單位的位置地方。
contentEntity.addChild(box) 將創建的立方體作為子實體添加到contentEntity中。
回到ImmersiveView,將剛剛的模型加入到場景當中:
struct ImmersiveView: View {
@StateObject var model = Day4ViewModel()
var body: some View {
RealityView { content in
// Add the initial RealityKit content
if let scene = try? await Entity(named: "Immersive", in: realityKitContentBundle) {
content.add(scene)
}
content.add(model.setupContentEntity())
}
}
}
在程式進入點也宣告使用ImmersiveSpace:
import SwiftUI
@main
struct TestVision2App: App {
var body: some Scene {
WindowGroup {
ContentView()
}
ImmersiveSpace(id: "ImmersiveSpace") {
ImmersiveView()
}
}
}
回到ContentView,稍微修改一下畫面內容:
import SwiftUI
import RealityKit
import RealityKitContent
struct ContentView: View {
@State private var showImmersiveSpace = false
@Environment(\.openImmersiveSpace) var openImmersiveSpace
@Environment(\.dismissImmersiveSpace) var dismissImmersiveSpace
var body: some View {
VStack {
Toggle("Show ImmersiveSpace", isOn: $showImmersiveSpace)
.font(.title)
.frame(width: 360)
.padding(24)
.glassBackgroundEffect()
}
.padding()
.onChange(of: showImmersiveSpace) { _, newValue in
Task {
if newValue {
await openImmersiveSpace(id: "ImmersiveSpace")
}
else {
await dismissImmersiveSpace()
}
}
}
}
}
這裡只會顯示一個開關,用來開啟沉浸式空間的內容。
如圖顯示:
開啟開關之後,就會出現一個立方體。
如圖顯示:
生成立方體的完成程式碼:
import SwiftUI
import RealityKit
import RealityKitContent
import ARKit
struct ImmersiveView: View {
@StateObject var model = Day4ViewModel()
var body: some View {
RealityView { content in
if let scene = try? await Entity(named: "Immersive", in: realityKitContentBundle) {
content.add(scene)
}
content.add(model.setupContentEntity())
}
}
}
@MainActor class Day4ViewModel: ObservableObject {
private var contentEntity = Entity()
func setupContentEntity() -> Entity {
let box = ModelEntity(mesh: .generateBox(width: 0.5, height: 0.5, depth: 0.5))
box.position = SIMD3(x: 0, y: 2, z: -1)
contentEntity.addChild(box)
return contentEntity
}
}
從 SwiftUI 到 Apple Vision Pro - SwiftUI 從零開始 Day26 [完]