J.Doe!
首先有一个小技巧。如果您想使用放下的 iphone 作为默认位置,您必须注意 sceneKit 上使用的轴与 DeviceMotion 使用的轴不同。检查轴:

(来源:apple.com)
您需要设置的第一件事是相机位置。当您启动 SceneKit 项目时,它会在 (0, 0, 15) 位置创建您的相机。这样做有一个问题:
eulerAngles = (0,0,0) 的值意味着对象将在平面 xz 中,但只要您从 Z 方向看,您就只能从侧面看到它。为了相当于放下 iphone,您需要将相机设置为从上方看。所以这就像你在手机上看它(就像一个相机,idk)
// create and add a camera to the scene
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
scene.rootNode.addChildNode(cameraNode)
// place the camera
cameraNode.position = SCNVector3(x: 0, y: 15, z: 0)
// but then you need to make the cameraNode face the ship (the origin of the axis), rotating it
cameraNode.eulerAngles.x = -Float(M_PI)*0.5 //or Float(M_PI)*1.5
有了这个,我们将从上面看到船,所以第一部分完成了。现在我们必须让船在设备旋转时保持“静止”(面向地面)。
//First we need to use SCNRendererDelegate
class GameViewController : UIViewController SCNSceneRendererDelegate{
private let motion = CMMotionManager();
...
然后在 viewDidLoad 上:
//important if you remove the sceneKit initial action from the ship.
//The scene would be static, and static scenes do not trigger the renderer update, setting the playing property to true forces that:
scnView.playing = true;
if(motion.deviceMotionAvailable){
motion.startDeviceMotionUpdates();
motion.deviceMotionUpdateInterval = 1.0/60.0;
}
然后我们去更新方法
查看轴:如果您比较 sceneKit 轴和 deviceMotion 轴,则 Y 轴和 Z 轴是“切换的”。Z在电话上,而在现场的一侧,Y在现场,而在电话的一侧。因此,分别与 X、Y 和 Z 轴相关联的俯仰、滚动和偏航将应用为俯仰、偏航和滚动。
请注意,我将滚动值设为正值,这是因为还有其他东西“切换”了。有点难以想象。看到设备运动的 Y 轴与场景的 Z 轴相关。现在想象一个物体沿着这个轴旋转,在相同的方向(例如顺时针方向),由于轴的布置,它们会朝相反的方向移动。(您也可以将滚动设置为负值,看看它是如何出错的)
func renderer(renderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {
if let rot = motion.deviceMotion?.attitude{
print("\(rot.pitch) \(rot.roll) \(rot.yaw)")
ship.eulerAngles.x = -Float(rot.pitch);
ship.eulerAngles.y = -Float(rot.yaw);
ship.eulerAngles.z = Float(rot.roll);
}
希望有帮助!再见!