重置 ARKit 坐标

Resetting ARKit coordinates

我有一个简单的问题。如果我想开始游戏并将棋盘放在我面前:

gameBoard!.position = SCNVector3(0, 0, -0.6)

这一直有效,直到我离开游戏并再次回来。我可以在镜头前或在我面前 0.6m 完全相同的位置显示游戏板吗?我可能已经移动到另一个位置。

"This works until I leave the game and come back again."

您无法在后台跟踪相机位置。每当您的应用程序进入后台并且相机关闭时,您就会失去自己的位置,并且 sessionWasInterrupted(_:) 将被调用。

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.

如果您想重置您的 ARSession,您必须暂停、删除所有节点并通过重置跟踪和删除锚点来重新运行您的会话。

我制作了一个重置​​按钮,每当我想重置时它都会执行:

@IBAction func reset(_ sender: Any) {

    sceneView.session.pause()
    sceneView.scene.rootNode.enumerateChildNodes { (node, stop) in
        node.removeFromParentNode()
    }
    sceneView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
}

或者把它放在你的session被中断函数中!

当您再次在 ARSession 上调用 run 时,使用选项 resetTracking 应该是可能的。

示例:

if let configuration = sceneView.session.configuration {
    sceneView.session.run(configuration,
                          options: .resetTracking)
}

在 ARKit 框架中重置 ARSession 非常简单:

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, ])
    }
}

希望对您有所帮助。