我的困境是这样的: 我有一个宇宙飞船定位在恒星和行星之间的空间。相机是作为太空船节点的孩子添加的,你总是看着宇宙飞船的后面(上面几个单位)。 我使用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))
})
}
并且旋转按预期工作。
现在我想把飞船朝着它面向的方向移动,但我不知道怎么做。我尝试过不同的方法但是我的失败很惨。
我已经无数次搜索过这个论坛好几天但没有运气。 我希望有人可以指出我(和我的太空飞船)正确的方向。
提前谢谢。
答案 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增加了方便的功能,可以获取节点的方向。在这种情况下,worldForward
属性是您想要的属性。此外,SCNNode
上返回SCNVector
的所有属性和矩阵类型现在都有返回simd类型的版本。因为simd已经具有算术运算符的重载,所以您不再需要为SCNVector
和SCNMatrix
类型添加算术覆盖的集合。
所以我们可以摆脱上面的getZForward
方法,只需要一行:
ship.simdPosition += ship.simdWorldFront * speed