私はCMMotionManagerを使用してデバイスの姿勢を取得しています。起動時には完全に機能するという特異な問題にぶち当たっていますが、停止して起動すると、停止して再起動した後、CMMotionManagerが正しくないヨーを報告するのはなぜですか?
startDeviceMotionUpdates(using: .xTrueNorthZVertical)
を使用して開始し、SceneKitシーンのレンダーループのヨー値を確認します。電話機をテーブルの上に平らに置き、90°回転させると、ヨーで90°の変化が示されます。完璧。
stopDeviceMotionUpdates()
を使用して停止した場合は、もう一度起動して同じ90°回転を実行すると、同じ90°の変化が見込まれます。しかし代わりに、それは回転の180°を示す!
これは初めて(using:)
の構文で開始するときに起きているようです。私はxCode 8.0を使ってiOS 10.0.2のiPhone 5でテストしています。
、再作成する「ゲーム」テンプレートを使用して新しいプロジェクトを作成し、以下にGameViewController.swiftのコードを置き換えるには:
import UIKit
import SceneKit
import CoreMotion
class GameViewController: UIViewController, SCNSceneRendererDelegate {
static let motionManager = CMMotionManager()
var scnView: SCNView!
var scnScene: SCNScene!
override func viewDidLoad() {
super.viewDidLoad()
scnView = self.view as! SCNView
scnView.delegate = self
scnScene = SCNScene()
scnView.scene = scnScene
scnView.isPlaying = true
GameViewController.motionManager.startDeviceMotionUpdates(using: .xTrueNorthZVertical)
// stop and start it again to cause doubling
GameViewController.motionManager.stopDeviceMotionUpdates()
GameViewController.motionManager.startDeviceMotionUpdates(using: .xTrueNorthZVertical)
}
func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
if let motion = GameViewController.motionManager.deviceMotion {
print(Int(motion.attitude.yaw * 180/M_PI))
}
}
}
このコードはCMMotionMangerを開始し、その後、すぐにそれを停止し、再度開始します。電話機を90度回転させると、180度のヨー角が表示されます。明らかに、これは実用的な例ではなく、問題を示す簡単なバージョンです。私の実際のユースケースでは、CMMotionManagerを使用しているSceneKitビューを閉じたときにCMMotionManagerを終了し、別のSceneKitビューを開いたときにCMMotionManagerを再起動します。
今のところ、私の回避策はCMMotionManagerを起動してから停止しないことです。それは動作しますが、具体的には "は、アプリケーションがデバイスモーションアップデートを処理しないようにするためにstopDeviceMotionUpdates()を呼び出さなければなりません"というメッセージが表示されるため、これは素晴らしい解決策ではありません。
なぜ、CMMotionManagerが停止して起動した後に間違った値を与えるのですか?修正するために何ができますか?
私の実際の使用例では、私が使用しているSceneKitビューが閉じられたときにCMMotionManagerを停止し、別のSceneKitビューが開いたときに/を再起動します。私の質問の例は、問題を示す最小限の例です。 – Robert