Search code examples
swiftswiftuirealitykitreality-composer

Can I control Reality Composer behaviors in RealityKit?


I would like to make a button using SwiftUI. When the button is pressed, the model will hide. I have already read the tutorial in this link (Creating a Trigger), but I don't know how to control it programmatically.

Here is my code:

struct VocabView : View {
    
    @State private var arView = ARView(frame: .zero)

    var body: some View {
        ZStack{
            ARViewContainer(arView: $arView)
                .ignoresSafeArea()
            VStack {
                Button("hide") {
                    hide()
                }    
            }
        }
    }
    
    func hide() {
        let demoScene = try! Experience1.loadDemo()
        if arView.scene.anchors.count > 0 {
            if arView.scene.anchors[0].isAnchored {
                demoScene.notifications.hide.post()
            }
        }
    }
}

struct ARViewContainer2: UIViewRepresentable {
    
    @Binding var arView: ARView
    
    func makeUIView(context: Context) -> ARView {
        
        let demoScene = try! Experience1.loadDemo()

        DispatchQueue.main.async {
            arView.scene.anchors.append(demoScene)
        }
        
        return arView
        
    } 
}

Here is the configuration in Reality Composer:

enter image description here


Solution

  • You are loading your model twice – at first in makeUIView() method and secondly in hide() method. Try my version.

    import SwiftUI
    import RealityKit
    
    struct ContentView : View {
    
        @State private var arView = ARView(frame: .zero)
        @State private var scene = try! Experience.loadBox()
    
        var body: some View {
            ZStack{
                ARViewContainer(arView: $arView, scene: $scene)
                    .ignoresSafeArea()
                VStack {
                    Spacer()
                    Button("Hide Model") { hideModel() }
                }
            }
        }
        private func hideModel() {
            if arView.scene.anchors.count > 0 {
                if arView.scene.anchors[0].isAnchored {
                    scene.notifications.notify.post()
                }
            }
        }
    }
    

    enter image description here

    struct ARViewContainer : UIViewRepresentable {
    
        @Binding var arView: ARView
        @Binding var scene: Experience.Box
        
        func makeUIView(context: Context) -> ARView {
            arView.scene.anchors.append(scene)
            return arView
        }
        func updateUIView(_ view: ARView, context: Context) { }
    }
    

    enter image description here