正如标题所述,在我旋转我的船舶节点之后,我想要“go”按钮使船舶在旋转后沿着它现在面向的方向行进。目前,按下“go”按钮会使船继续沿着世界的z轴移动,而不是船舶朝向的方向(显然因为我没有任何代码,否则告诉它)。
我尝试过使用worldTransform
和convertPosition:toNode:
但目前没有运气。
在ViewController中:
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.
}
}
在SpaceShip()中:
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 :(得分:0)
transfomPosition
无效,因为它会转换某个位置,但您不希望这样,您想要转换方向。这也是SCNVector3
,但完全不同,因为您只需要应用旋转,而不是翻译。
使用transformVector
或直接使用worldFront
,这是iOS 11中的新功能。