2023 EssentialsSpatial Computing
WWDC23 · 31 min · Essentials / Spatial Computing
Develop your first immersive app
Find out how you can build immersive apps for visionOS using Xcode and Reality Composer Pro. We’ll show you how to get started with a new visionOS project, use Xcode Previews for your SwiftUI development, and take advantage of RealityKit and RealityView to render 3D content.
Watch at developer.apple.com ↗Chapters
Code shown on screen · 7 snippets
Glass background effect
VStack {
Toggle("Enlarge RealityView Content", isOn: $enlarge)
.toggleStyle(.button)
}
.padding()
.glassBackgroundEffect() RealityView
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().targetedToAnyEntity().onEnded { _ in
enlarge.toggle()
}) ImmersiveView
// MyFirstImmersiveApp.swift
@main
struct MyFirstImmersiveApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}.windowStyle(.volumetric)
ImmersiveSpace(id: "ImmersiveSpace") {
ImmersiveView()
}
}
} Size that fits
#Preview {
ImmersiveView()
.previewLayout(.sizeThatFits)
} openImmersiveSpace
struct ContentView: View {
(\.openImmersiveSpace) var openImmersiveSpace
var body: some View {
Button("Open") {
Task {
await openImmersiveSpace(id: "ImmersiveSpace")
}
}
}
} Entity targeting
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)!")
})
}
} Move animation
.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
)
}) Related sessions
-
28 min -
24 min -
21 min -
24 min -
20 min -
32 min -
34 min -
26 min