2017-07-20 57 views
1

正如標題所述,在旋轉我的船節點之後,我希望「go」按鈕使船舶沿着它的方向行進現在面臨輪換之後。目前,按下「開始」按鈕會使船繼續沿着世界的z軸而不是船的方向移動(顯然是因爲我沒有任何其他的代碼告訴它)。在旋轉之後努力沿節點移動節點(Swift | ARKit | SceneKit)

我已嘗試使用worldTransformconvertPosition:toNode:目前沒有運氣。

在視圖控制器:

let ship = SpaceShip(); 
    let SHIP_SPEED: Float = 3.00; 
    let scene = SCNScene(); 


    var timer = Timer(); 

    var upPressed = false; 
    var rightPressed = false; 
    var downPressed = false; 
    var leftPressed = false; 
    var goPressed = false; 
    var stopPressed = false; 
    var firePressed = false; 

    //initial angles for rotating ship 
    //if ship is flipping upside down, it is because of these 
    /* var xAngle: SCNMatrix4? 
    var yAngle: SCNMatrix4? 
    var zAngle: SCNMatrix4? */ 

    @IBOutlet weak var sceneView: ARSCNView! 

    @IBAction func upBtnDown(_ sender: Any) { 
     upPressed = true; 
    } 
    @IBAction func upBtnUp(_ sender: Any) { 
     upPressed = false; 
     ship.rotateShip(ship.getNode(), x: 180, y: 0, z: 180); 
    } 

    @IBAction func rightBtnDown(_ sender: Any) { 
     rightPressed = true; 

    } 

    @IBAction func rightBtnUp(_ sender: Any) { 
     rightPressed = false; 
     ship.rotateShip(ship.getNode(), x: 180, y: 0, z: 180); 
    } 

    @IBAction func downBtnDown(_ sender: Any) { 
     downPressed = true; 
    } 

    @IBAction func downBtnUp(_ sender: Any) { 
     downPressed = false; 
     ship.rotateShip(ship.getNode(), x: 180, y: 0, z: 180); 
    } 

    @IBAction func leftBtnDown(_ sender: Any) { 
     leftPressed = true; 

    } 

    @IBAction func leftBtnUp(_ sender: Any) { 
     leftPressed = false; 
     //ship.rotateShip(ship.getNode(), x: 180, y: 0, z: 180); 
    } 

    @IBAction func goBtnDown(_ sender: Any) { 

     goPressed = true; 
    } 

    @IBAction func goBtnUp(_ sender: Any) { 
     goPressed = false; 
    } 

    @IBAction func stopBtnDown(_ sender: Any) { 
     stopPressed = true; 
    } 

    @IBAction func stopBtnUp(_ sender: Any) { 
     stopPressed = false; 
    } 


    @IBAction func fireBtnDown(_ sender: Any) { 
     firePressed = true; 
    } 

    @IBAction func fireBtnUp(_ sender: Any) { 
     firePressed = false; 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     //set scene from storyboard to scene variable 
     sceneView.scene = scene; 
     sceneView.scene.physicsWorld.contactDelegate = self; 
     sceneView.delegate = self; 

    } 

    override func viewWillAppear(_ animated: Bool) { 

     super.viewWillAppear(animated); 

     let configuration = ARWorldTrackingSessionConfiguration(); 

     sceneView.session.run(configuration); 

     addShip(); 

    } 

    func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) { 

     ship.physicsBody?.velocity = SCNVector3(0,0,0); 

     if(upPressed == true) { 
      ship.physicsBody?.velocity.y = SHIP_SPEED; 
      ship.rotateShip(ship.getNode(), x: 170, y: 0, z: 180); 
     } else if (rightPressed == true) { 
      ship.physicsBody?.velocity.x = SHIP_SPEED; 
      ship.rotateShip(ship.getNode(), x: 180, y: 0, z: 170); 
     } else if (downPressed == true) { 
      ship.physicsBody?.velocity.y = -SHIP_SPEED; 
      ship.rotateShip(ship.getNode(), x: 190, y: 0, z: 180); 
     } else if (leftPressed == true) { 
      //ship.physicsBody?.velocity.x = -SHIP_SPEED; 
      ship.rotateShip(ship.getNode(), x: 180, y: 15, z: 190); 
      print(ship.getNode().rotation); 

     } else if (goPressed == true) { 
      ship.physicsBody?.velocity.z = -SHIP_SPEED; 
     } else if (stopPressed == true) { 
      ship.physicsBody?.velocity.z = SHIP_SPEED; 
     } 

    } 

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

    func addShip() { 
     ship.loadModel(); 

     ship.position = SCNVector3(0, 0, -2); 

     sceneView.scene.rootNode.addChildNode(ship); 
    } 

    func degToRad(deg: Float) -> Float{ 
     return deg/180 * Float(M_PI) 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 


} 

在飛船():

class SpaceShip: SCNNode { 

    var node = SCNNode(); 

    func loadModel() { 
     guard let virtualObjectScene = SCNScene(named: "art.scnassets/ship.scn") else {return}; 

     let wrapperNode = SCNNode(); 

     for child in virtualObjectScene.rootNode.childNodes { 
      wrapperNode.addChildNode(child); 
     } 

     node = wrapperNode.childNodes[0]; 
     let shape = SCNPhysicsShape(node: node, options: nil); 
     self.physicsBody = SCNPhysicsBody(type: .dynamic, shape: shape); 
     self.physicsBody?.isAffectedByGravity = false; 

     rotateShip(node, x: 180, y: 0, z: 180); 

     self.addChildNode(wrapperNode); 
    } 

    func getNode() -> SCNNode { 
     return node; 
    } 

    func rotateShip(_ node: SCNNode, x: Float, y: Float, z: Float){ 
     //original angles 
     let xAngle = SCNMatrix4MakeRotation(degToRad(deg: x), 1, 0, 0); 
     let yAngle = SCNMatrix4MakeRotation(degToRad(deg: y), 0, 1, 0); 
     let zAngle = SCNMatrix4MakeRotation(degToRad(deg: z), 0, 0, 1); 


     let rotationMatrix = SCNMatrix4Mult(SCNMatrix4Mult(xAngle, yAngle), zAngle); 

     node.pivot = SCNMatrix4Mult(rotationMatrix, node.transform); 
    } 

    func degToRad(deg: Float) -> Float{ 
     return deg/180 * Float(M_PI) 
    } 

} 

謝謝

回答

0

transfomPosition不起作用,因爲它轉換的位置,但你不希望出現這種情況,你想變換一個方向。這也是一個SCNVector3,但完全不同,因爲你只想要應用輪換,而不是轉換

直接使用transformVector或使用worldFront,這是iOS 11中的新功能。