1

On my project, I load reality files synchronously like this:

struct: DemoView: View {
    @State private var arView = ARView(frame: .zero)
    @State private var Scene1 = try! Experience1.loadScene1()

    var body: some View {
       ZStack {
         ARViewContainer(arView: $arView, Scene1: $Scene1)
           .ignoresSafeArea()
         Button("play") {
           Scene1.notifications.replay.post()
         }
       }
    }
}

struct ARViewContainer: UIViewRepresentable {
    @Binding var arView: ARView
    @Binding var Scene1: Experience1.Scene1

    func makeUIView(context: Context) -> ARView {
        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
            arView.scene.anchors.append(Scene1)
        }
     
        return ARView
    }
}

Since my model in Reality Scene has a lot of polygons, can I turn to load reality files asynchronously?

kkk
  • 187
  • 8

1 Answers1

1

Async loading method for Reality Composer files

Try the following code when you need to load a Reality Composer scene asynchronously:

import SwiftUI
import RealityKit

struct ContentView : View {
    var body: some View {
        ARViewContainer().ignoresSafeArea()
    }
}

struct ARViewContainer : UIViewRepresentable {
    
    let arView = ARView(frame: .zero)
    let anchor = AnchorEntity()
    
    func makeUIView(context: Context) -> ARView {
        
        Experience.loadBoxAsync(completion: { result in
            do {
                let heavyBoxScene = try result.get()
                arView.scene.anchors.append(heavyBoxScene)
            } catch {
                print("Error: \(error.localizedDescription)")
            }
        })
        return arView
    }
    func updateUIView(_ vue: ARView, context: Context) { }
}

Async loading method for USDZ files

Try the following code when you need to load .usdz model asynchronously:

import SwiftUI
import RealityKit
import Combine

struct ARViewContainer : UIViewRepresentable {
    
    @State var cancellable: AnyCancellable? = nil
    let anchor = AnchorEntity()
    let arView = ARView(frame: .zero)
    
    func makeUIView(context: Context) -> ARView {

        DispatchQueue.main.async {

            cancellable = Entity.loadModelAsync(named: "character.usdz").sink(
                
                receiveCompletion: { completion in
                    if case let .failure(error) = completion {
                        print("Unable to load a model due to \(error)")
                    }
                    self.cancellable?.cancel()
                    
                }, receiveValue: { [self] (model: Entity) in
                    anchor.addChild(model)
                    anchor.position.z = -1.0
                    arView.scene.anchors.append(anchor)
                })
        }
        return arView
    }
    func updateUIView(_ vue: ARView, context: Context) { }
}

P. S.

Answer to your next question.

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
  • I would like to use the scene with notifications in Reality Composer like `Scene1.notifications.replay.post()` . So, can I load the scene in ContentView and binding to the ARViewContainer for appending the scene? – kkk Mar 08 '23 at 12:36
  • 1
    Of course, you can. – Andy Jazz Mar 08 '23 at 12:53
  • I moved `Experience.loadBoxAsync(completion: { })` into the ContentView, but it didn't work. Could you advice me how to load in ContentView asynchronously? – kkk Mar 08 '23 at 13:06