How to initialize .nonAR mode properly?

I'm able to use nonAR (virtual reality) mode of the RealityKit with following initialization:


arView.cameraMode = .nonAR

let config = ARWorldTrackingConfiguration()

config.planeDetection = .horizontal

arView.session.run(config, options: [])


... but obviously ARWorldTrackingConfiguration is not a good idea in nonAR. How should I initialize it properly? I see nothing if I only set the cameraMode (without additional configuration).

Accepted Reply

In the SwiftUI example they use `.zero` for the frame, might be best to just use the same as it will take it to full screen either way.


For the box, in order to avoid any issues, just create and add a box manually instead, also the SwiftUI Preview will basically use the simulator, and the initialiser I mentioned is actually not available for the simulator, you'll need to put in a targetEnvironment check:


struct ARViewContainer: UIViewRepresentable {
    func makeUIView(context: Context) -> ARView {
        #if targetEnvironment(simulator)
        let arView = ARView(frame: .zero)
        #else
        let arView = ARView(frame: .zero, cameraMode: .nonAR, automaticallyConfigureSession: false)
        #endif

        let newAnchor = AnchorEntity(world: [0, 0, -1])
        let newBox = ModelEntity(mesh: .generateBox(size: 0.3))
        newAnchor.addChild(newBox)
        arView.scene.anchors.append(newAnchor)

        return arView

    }
    func updateUIView(_ uiView: ARView, context: Context) {}
}


The simulator automatically uses cameraMode .nonAR, as it has no other choice and cannot be changed to `.ar`.

Replies

Your scene may be empty, in which case it would be normal to see nothing. Add a cube to the position [0, 0, -1], it should appear in the middle of your view, since the default camera should be looking at [0,0,-1] from [0,0,0].



If you're changing the camera mode from .ar to .nonAR, and don't plan on actually using the session for anything, then it might be best to run arView.session.pause() after, instead of leaving it.


A better (IMO) way to initialize a nonAR ARView would be using this initializer, but if you're using storyboards then just changing the camera mode should work just as well. Also, if you want to change the background color, set this parameter:


self.arView.environment.background = .color(.blue)

Thanks maxxfrazer,


Actually I'm using SwiftUI. I tried to set the cube position as [0,0,-1]. See below.

struct ContentView : View {
    var body: some View {
        return ARViewContainer().edgesIgnoringSafeArea(.all)
    }
}
struct ARViewContainer: UIViewRepresentable {
    func makeUIView(context: Context) -> ARView {
        let arView = ARView(frame: .zero)
        arView.cameraMode = .nonAR
        let boxAnchor = try! Experience.loadBox()
        arView.scene.anchors.append(boxAnchor)
        boxAnchor.setPosition([0,0,-1], relativeTo: nil)
        return arView
    }
    func updateUIView(_ uiView: ARView, context: Context) {}
}

I also tried to use the other initializer for the ARView. See below.

struct ARViewContainer: UIViewRepresentable {
    func makeUIView(context: Context) -> ARView {
        let frameRect = CGRect(x: 0, y: 0, width: 100, height: 100)
        let cameraMode = ARView.CameraMode.nonAR
        let arView = ARView(frame: frameRect, cameraMode: cameraMode, automaticallyConfigureSession: false)
        let boxAnchor = try! Experience.loadBox()
        arView.scene.anchors.append(boxAnchor)
        boxAnchor.setPosition([0,0,-1], relativeTo: nil)
        return arView
    }
    func updateUIView(_ uiView: ARView, context: Context) {}
}

...but that did not help either (I'm not sure how to use the "frame"). Any ideas?

In the SwiftUI example they use `.zero` for the frame, might be best to just use the same as it will take it to full screen either way.


For the box, in order to avoid any issues, just create and add a box manually instead, also the SwiftUI Preview will basically use the simulator, and the initialiser I mentioned is actually not available for the simulator, you'll need to put in a targetEnvironment check:


struct ARViewContainer: UIViewRepresentable {
    func makeUIView(context: Context) -> ARView {
        #if targetEnvironment(simulator)
        let arView = ARView(frame: .zero)
        #else
        let arView = ARView(frame: .zero, cameraMode: .nonAR, automaticallyConfigureSession: false)
        #endif

        let newAnchor = AnchorEntity(world: [0, 0, -1])
        let newBox = ModelEntity(mesh: .generateBox(size: 0.3))
        newAnchor.addChild(newBox)
        arView.scene.anchors.append(newAnchor)

        return arView

    }
    func updateUIView(_ uiView: ARView, context: Context) {}
}


The simulator automatically uses cameraMode .nonAR, as it has no other choice and cannot be changed to `.ar`.

Excellent! Thanks maaxxfrazer!


That works (I'm not using simulator).