I have a simple question. If I wanted to start a game and place the board right in front of me:
gameBoard!.position = SCNVector3(0, 0, -0.6)
This works until I leave the game and come back again. Can I show the game board in exact same position in front of camera or 0.6m
in front of me? I might have physically moved to another position.
If you want to reset you ARSession, you have to pause, remove all nodes and rerun your session by resetting tracking and removing anchors.
I made a reset button that does it whenever i want to reset:
@IBAction func reset(_ sender: Any) {
sceneView.session.pause()
sceneView.scene.rootNode.enumerateChildNodes { (node, stop) in
node.removeFromParentNode()
}
sceneView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
}
Or put it in your session was interrupted function!
This should be possible using the option resetTracking when you call run
on your ARSession
again.
Example:
if let configuration = sceneView.session.configuration {
sceneView.session.run(configuration,
options: .resetTracking)
}
"This works until I leave the game and come back again."
You can't track camera position in the background. Whenever your app goes to the background and camera turns off, you're losing your position, and sessionWasInterrupted(_:) will be called.
A session is interrupted when it fails to receive camera or motion
sensing data. Session interruptions occur whenever camera capture is
not available—for example, when your app is in the background or there
are multiple foreground apps—or when the device is too busy to process
motion sensor data.
To reset ARSession in ARKit framework is quite easy:
class ViewController: UIViewController, ARSCNViewDelegate, ARSessionDelegate {
@IBOutlet var arView: ARSCNView!
@IBOutlet weak var sessionInfoLabel: UILabel!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let configuration = ARWorldTrackingConfiguration()
configuration.planeDetection = [.horizontal, .vertical]
arView.session.run(configuration)
arView.session.delegate = self
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
arView.session.pause()
}
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let planeAnchor = anchor as? ARPlaneAnchor else {
return
}
let plane = Plane(anchor: planeAnchor, in: arView)
node.addChildNode(plane)
}
func sessionInterruptionEnded(_ session: ARSession) {
resetSessionTracking()
sessionInfoLabel.text = "ARSession's interruption has ended"
}
private func resetSessionTracking() {
let config = ARWorldTrackingConfiguration()
config.planeDetection = [.vertical, .horizontal]
arView.scene.rootNode.enumerateChildNodes { (childNode, _) in
childNode.removeFromParentNode()
}
arView.session.run(config, options: [.removeExistingAnchors,
.resetTracking, ])
}
}
Hope this helps.