-
Build spatial experiences with RealityKit
Discover how RealityKit can bring your apps into a new dimension. Get started with RealityKit entities, components, and systems, and learn how you can add 3D models and effects to your app on visionOS. We'll also take you through the RealityView API and demonstrate how to add 3D objects to windows, volumes, and spaces to make your apps more immersive. And we'll explore combining RealityKit with spatial input, animation, and spatial audio.
Chapitres
- 0:00 - Introduction
- 2:50 - RealityKit and SwiftUI
- 9:36 - Entities and components
- 12:20 - RealityView
- 15:37 - Input, animation and audio
- 23:00 - Custom systems
- 26:15 - Wrap-up
Ressources
Vidéos connexes
WWDC23
- Develop your first immersive app
- Enhance your spatial computing app with RealityKit
- Evolve your ARKit app for spatial experiences
- Explore the USD ecosystem
- Get started with building apps for spatial computing
- Go beyond the window with SwiftUI
- Meet ARKit for spatial computing
- Meet Reality Composer Pro
- Meet SwiftUI for spatial computing
- Meet UIKit for spatial computing
- Take SwiftUI to the next dimension
- Work with Reality Composer Pro content in Xcode
-
Rechercher dans cette vidéo…
-
-
3:40 - Model3D
import SwiftUI import RealityKit struct GlobeModule: View { var body: some View { Model3D(named: "Globe") { model in model .resizable() .scaledToFit() } placeholder: { ProgressView() } } } -
5:52 - Volumetric window
import SwiftUI import RealityKit // Define a volumetric window. struct WorldApp: App { var body: some SwiftUI.Scene { // ... WindowGroup(id: "planet-earth") { Model3D(named: "Globe") } .windowStyle(.volumetric) .defaultSize(width: 0.8, height: 0.8, depth: 0.8, in: .meters) } } -
7:31 - ImmersiveSpace
import SwiftUI import RealityKit // Define a immersive space. struct WorldApp: App { var body: some SwiftUI.Scene { // ... ImmersiveSpace(id: "objects-in-orbit") { RealityView { content in // ... } } } } -
12:40 - RealityView
import SwiftUI import RealityKit struct Orbit: View { let earth: Entity var body: some View { RealityView { content in content.add(earth) } } } -
12:54 - RealityView asynchronous loading and entity positioning
import SwiftUI import RealityKit struct Orbit: View { var body: some View { RealityView { content in async let earth = ModelEntity(named: "Earth") async let moon = ModelEntity(named: "Moon") if let earth = try? await earth, let moon = try? await moon { content.add(earth) content.add(moon) moon.position = [0.5, 0, 0] } } } } -
13:54 - Earth rotation
import SwiftUI import RealityKit struct RotatedModel: View { var entity: Entity var rotation: Rotation3D var body: some View { RealityView { content in content.add(entity) } update: { content in entity.orientation = .init(rotation) } } } -
14:27 - Converting co-ordinate spaces
import SwiftUI import RealityKit struct ResizableModel: View { var body: some View { GeometryReader3D { geometry in RealityView { content in if let earth = try? await ModelEntity(named: "Earth") { let bounds = content.convert(geometry.frame(in: .local), from: .local, to: content) let minExtent = bounds.extents.min() earth.scale = [minExtent, minExtent, minExtent] } } } } } -
14:56 - Play an animation
import SwiftUI import RealityKit struct AnimatedModel: View { @State var subscription: EventSubscription? var body: some View { RealityView { content in if let moon = try? await Entity(named: "Moon"), let animation = moon.availableAnimations.first { moon.playAnimation(animation) content.add(moon) } subscription = content.subscribe(to: AnimationEvents.PlaybackCompleted.self) { // ... } } } } -
18:31 - Adding a drag gesture
import SwiftUI import RealityKit struct DraggableModel: View { var earth: Entity var body: some View { RealityView { content in content.add(earth) } .gesture(DragGesture() .targetedToEntity(earth) .onChanged { value in earth.position = value.convert(value.location3D, from: .local, to: earth.parent!) }) } } -
20:20 - Playing a transform animation
// Playing a transform animation let orbit = OrbitAnimation(name: "Orbit", duration: 30, axis: [0, 1, 0], startTransform: moon.transform, bindTarget: .transform, repeatMode: .repeat) if let animation = try? AnimationResource.generate(with: orbit) { moon.playAnimation(animation) } -
22:12 - Adding audio
// Create an empty entity to act as an audio source. let audioSource = Entity() // Configure the audio source to project sound out in a tight beam. audioSource.spatialAudio = SpatialAudioComponent(directivity: .beam(focus: 0.75)) // Change the orientation of the audio source (rotate 180º around the Y axis). audioSource.orientation = .init(angle: .pi, axis: [0, 1, 0]) // Add the audio source to a parent entity, and play a looping sound on it. if let audio = try? await AudioFileResource(named: "SatelliteLoop", configuration: .init(shouldLoop: true)) { satellite.addChild(audioSource) audioSource.playAudio(audio) } -
23:47 - Defining a custom component
import RealityKit // Components are data attached to an Entity. struct TraceComponent: Component { var mesh = TraceMesh() } // Entities contain components, identified by the component’s type. func updateTrace(for entity: Entity) { var component = entity.components[TraceComponent.self] ?? TraceComponent() component.update() entity.components[TraceComponent.self] = component } // Codable components can be added to entities in Reality Composer Pro. struct PointOfInterestComponent: Component, Codable { var name = "" } -
24:51 - Defining a system
import SwiftUI import RealityKit // Systems supply logic and behavior. struct TraceSystem: System { static let query = EntityQuery(where: .has(TraceComponent.self)) init(scene: Scene) { // ... } func update(context: SceneUpdateContext) { // Systems often act on all entities matching certain conditions. for entity in context.entities(Self.query, updatingSystemWhen: .rendering) { addCurrentPositionToTrace(entity) } } } // Systems run on all RealityKit content in your app once registered. struct MyApp: App { init() { TraceSystem.registerSystem() } }
-