如何在Arkit 1.5中施加力后跟踪节点的位置

时间:2018-03-12 14:21:14

标签: swift arkit

一旦节点开始移动,由于某种原因,它就会停止跟踪节点的位置。这就是我的意思:

 internal func launchNode(force:Float) {
    let force = force * 0.004

    currNode.physicsBody = SCNPhysicsBody(type: .dynamic, shape: nil)
    currNode.physicsBody?.mass = 0.05

    let direction = currNode.worldFront + SCNVector3(force, -force, -force)
    currNode.physicsBody?.applyForce(direction, asImpulse: true)

}

节点正在移动,这很棒,但我想跟踪节点移动时的当前位置:

func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {

guard currNode != nil else { return }

    print("simdWorldPosition: \(currNode.simdWorldPosition.y)  position: \(currNode.position.y) simWorldPosition: \(currNode.simdWorldPosition.y)  simPosition: \(currNode.simdPosition.y)")
}

这些属性都没有更新位置,所以我知道我错过了什么。我想在它到达某个位置(y坐标)时阻止它移动。如果有人在.applyForce之后成功跟踪节点的位置,如果你能指出我做错了什么,或许对你有用的话,我会非常感激。感谢。

更新

这是我用来测试它的一些代码。

我在此ViewController的开头声明了节点:

var currNode = SCNNode()

您可以尝试以下测试来跟踪ARKit默认项目的节点位置:

//call this once your scene is set
func addTapGestureToSceneView() {
    let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.didTap(withGestureRecognizer:)))
    sceneView.addGestureRecognizer(tapGestureRecognizer)
}

@objc func didTap(withGestureRecognizer recognizer: UIGestureRecognizer) {
    let tapLocation = recognizer.location(in: sceneView)
    let hitTestResults = sceneView.hitTest(tapLocation)
    guard let node = hitTestResults.first?.node else { return }
    if node.name == "shipMesh" {
        currNode = node
        moveShip()
    }
}

  internal func moveShip() {
    let force = 2 * 0.004
    currNode.physicsBody = SCNPhysicsBody(type: .dynamic, shape: nil)
    currNode.physicsBody?.mass = 0.05
    let direction = currNode.worldFront + SCNVector3(force, -force, -force)
    currNode.physicsBody?.applyForce(direction, asImpulse: true)

}

  func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {

    print("simdWorldPosition: \(currNode.simdWorldPosition.y)  position: \(currNode.position.y) simWorldPosition: \(currNode.simdWorldPosition.y)  simPosition: \(currNode.simdPosition.y)")
}

1 个答案:

答案 0 :(得分:0)

所以您的问题的答案在同一行

使用node.presentation属性

func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {

    print("simdWorldPosition: \(currNode.presentation.simdWorldPosition.y)  position: \(currNode.presentation.position.y) simWorldPosition: \(currNode.presentation.simdWorldPosition.y)  simPosition: \(currNode.presentation.simdPosition.y)")
}

来自Apple Docs

  

当您使用隐式动画(请参见SCNTransaction)更改节点的属性时,即使动画节点的内容似乎已从旧的属性值过渡到新的属性,这些节点属性也会立即设置为其目标值。在动画过程中,SceneKit会维护一个称为表示节点的节点的副本,该节点的属性反映了由当前影响该节点的任何进行中的动画确定的瞬时值。

希望对您有帮助