如何在应用旋转后沿其指向的方向移动SCNNode

时间:2017-02-01 16:43:20

标签: rotation swift3 scenekit trigonometry

我的困境是这样的: 我有一个宇宙飞船定位在恒星和行星之间的空间。相机是作为太空船节点的孩子添加的,你总是看着宇宙飞船的后面(上面几个单位)。 我使用CoreMotion像这样旋转宇宙飞船:

    func startMonitoringMotion() {
    self.motionManager?.startDeviceMotionUpdates(to: OperationQueue.main, withHandler: { (data, error) in
        guard let data = data else { return }

        let attitude: CMAttitude = data.attitude
        self.ship.eulerAngles = SCNVector3Make(Float(attitude.roll - M_PI_2), Float(attitude.yaw), Float(attitude.pitch))
    })
}

并且旋转按预期工作。

现在我想把飞船朝着它面向的方向移动,但我不知道怎么做。我尝试过不同的方法但是我的失败很惨。

我已经无数次搜索过这个论坛好几天但没有运气。 我希望有人可以指出我(和我的太空飞船)正确的方向。

提前谢谢。

1 个答案:

答案 0 :(得分:3)

我发现最简单的方法是获取节点worldTransform属性的第三行,该属性对应于其z-forward轴。

func getZForward(node: SCNNode) -> SCNVector3 {
    return SCNVector3(node.worldTransform.m31, node.worldTransform.m32, node.worldTransform.m33)
}

ship.position += getZForward(ship) * speed // nb scalar multiply requires overload of * func
// if node has a physics body, you might need to use the presentationNode, eg:
// getZForward(ship.presentationNode)
// though you probably don't want to be directly modifying the position of a node with a physics body

请参阅此处的讨论Getting direction that SCNNode is facing

iOS 11更新

iOS 11增加了方便的功能,可以获取节点的方向。在这种情况下,worldForward属性是您想要的属性。此外,SCNNode上返回SCNVector的所有属性和矩阵类型现在都有返回simd类型的版本。因为simd已经具有算术运算符的重载,所以您不再需要为SCNVectorSCNMatrix类型添加算术覆盖的集合。

所以我们可以摆脱上面的getZForward方法,只需要一行:

ship.simdPosition += ship.simdWorldFront * speed