1

From my question here, I would like to use the scene with notifications in Reality Composer like

Scene1.notifications.replay.post()

Therefore, I load the scene in ContentView and binding to the ARViewContainer for appending the scene, but it didn't work.

How can I do it?

Here's my code:

struct: ContentView: View {
    @State private var arView = ARView(frame: .zero)
    @State private var Scene1 = Experience.loadSceneAsync(completion: { result in
        do {
            let Scene = try result.get()
        } catch {
            print("Error")
        }
    })

    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 {
        
        arView.scene.anchors.append(Scene1)
     
        return ARView
    }
}
Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
kkk
  • 187
  • 8

1 Answers1

2

Async-loaded models from Reality Composer scene

In order to implement the Combine's publisher/subscriber logics, we need to create a class with a @Published property wrapper, in which we will place the RealityKit's asynchronous loading method.

@Published and @ObservedObject wrappers used here to manage state from external objects.


enter image description here


import SwiftUI
import RealityKit

class Catcher: ObservableObject {
        
    @Published var scene = Experience.Box()
    
    func sceneLoader() {
        Experience.loadBoxAsync(completion: { result in
            do {
                self.scene = try result.get()
                self.scene.steelBox?.scale *= 4
            } catch {
                print("Error: \(error.localizedDescription)")
            }
        })
    }

    func notificationLoader() {
        if scene.notifications.allNotifications.count > 0 {
            self.scene.notifications.replay.post()
        }
    }
}

struct ContentView : View {
    
    @State private var boolean: Bool = false
    
    var body: some View {
        ZStack {
            ARViewContainer(boolean: $boolean)
                .ignoresSafeArea()
            VStack {
                Spacer()
                Button("Play Animation") {
                    boolean = true
                }
            }
        }
    }
}

struct ARViewContainer : UIViewRepresentable {
    
    @ObservedObject var catcher = Catcher()
    @Binding var boolean: Bool
    var arView = ARView(frame: .zero)
    
    func makeUIView(context: Context) -> ARView {
        catcher.sceneLoader()
        return arView
    }
    func updateUIView(_ vue: ARView, context: Context) {

        vue.scene.anchors.append(catcher.scene)
        
        if boolean {
            catcher.notificationLoader()
        }
        DispatchQueue.main.async {
            if boolean {
                boolean = false
            }
        }
    }
}

enter image description here

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220