美文网首页ARKit开发
14-Motion-Control运动控制

14-Motion-Control运动控制

作者: 095b62ead3cd | 来源:发表于2020-06-15 21:07 被阅读0次

    文章选自掘金苹果API搬运工的文章[SceneKit专题]14-Motion-Control运动控制
    主要记录自己在学习ARKit的过程中看到的好的文章,避免到时候链接失效无法找到原文的情况,非常感谢原博主的辛勤付出,也在此分享出来跟大家一起学习。

    相机约束

    // 1.拿到相机节点
    cameraNode = scnScene.rootNode.childNodeWithName("camera", recursively:
    true)!
    // 2.添加lookAt约束,让相机始终朝向ballNode小球节点
    let constraint = SCNLookAtConstraint(target: ballNode)
    cameraNode.constraints = [constraint]
    

    Gimbal locking万向节锁
    当使用SCNLookAtConstraint时,Scene Kit不管被朝向的对象如何移动,旋转都会让相机对着他.但是有些时候会转到一些奇怪的角度,导致相机发生向左或向右的倾斜,对于灯光是没问题的,但相机就不可以,我们总是希望相机保持水平方向.
    因此用到万向节锁

    constraint.gimbalLockEnabled = true
    

    更改物体的运动状态和位置

    //根据手机加速度传感器数据,移动小球
    func updateMotionControl() {
        // 1.每0.1秒更新传感器参数,构造为向量
        if game.state == GameStateType.Playing {
          motion.getAccelerometerData(0.1) { (x,y,z) in
            self.motionForce = SCNVector3(x: Float(x) * 0.05, y:0, z: Float(y+0.8) * -0.05)
          }
          // 2.小球的速度改变
          ballNode.physicsBody!.velocity += motionForce
        }
      }
      
    //让相机跟着小球平滑移动
      func updateCameraAndLights() {
        // 1.小球呈现位置与相机当前位置的差,每次移动0.01
        let lerpX = (ballNode.presentationNode.position.x - cameraFollowNode.position.x) * 0.01
        let lerpY = (ballNode.presentationNode.position.y - cameraFollowNode.position.y) * 0.01
        let lerpZ = (ballNode.presentationNode.position.z - cameraFollowNode.position.z) * 0.01
        cameraFollowNode.position.x += lerpX
        cameraFollowNode.position.y += lerpY
        cameraFollowNode.position.z += lerpZ
        // 2.灯光位置也跟随相机位置变化
        lightFollowNode.position = cameraFollowNode.position
        // 3.进入暂停状态时,相机欧拉角沿y轴旋转0.005
        if game.state == GameStateType.TapToPlay {
          cameraFollowNode.eulerAngles.y += 0.005
        }
      }
    

    传感器工具类代码

    import Foundation
    import CoreMotion
    
    class CoreMotionHelper {
      
      let motionManager = CMMotionManager()
      
      init() {
      }
      
      func getAccelerometerData(interval: NSTimeInterval = 0.1, closure: ((x: Double, y: Double, z: Double) -> ())? ){
        
        if motionManager.accelerometerAvailable {
          
          motionManager.accelerometerUpdateInterval = interval
          
          motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue()) {
            (data: CMAccelerometerData?, error: NSError?) -> Void in
            
            if closure != nil{
              closure!(x: data!.acceleration.x,y: data!.acceleration.y,z: data!.acceleration.z)
            }
            
          }
        }
      }
    }
    

    相关文章

      网友评论

        本文标题:14-Motion-Control运动控制

        本文链接:https://www.haomeiwen.com/subject/evzhxktx.html