How to move around in a SceneKit scene?

182 Views Asked by At

In my macCatalyst app, I try to make a SCNScene where the user should be able to move around (with w, a, s and d) but It doesn't work. I want

  • to make the possibility to just move around in the scene first
  • and then adjust it to the direction that the camera is facing

But I have already failed with the first step.

I tried to set the SCNView's point of view to a new SCNNode and tried to move that around:

// initializing the scene
let scene = SCNScene(named: "SceneKit Scene.scn")!
sceneView.scene = scene
// try to set the point of the scene
let node = SCNNode()
node.position = SCNVector3(x: 10, y: 10, z: 10)
sceneView.pointOfView = node

But it changed nothing.

I have also tried to move the node (that is holding all other nodes of the scene inside around)

override func pressesBegan(_ presses: Set<UIPress>, 
                          with event: UIPressesEvent) {

    guard let press = presses.first else { return }
    guard let key = press.key else { return }

    if key.charactersIgnoringModifiers == "w" {
        node.position.z += 1
    }
}

Which does work better, but it does not feel like going around in the scene, and if I move around the facing of the camera, I move into the wrong direction.

So how do I fix this?

1

There are 1 best solutions below

0
On BEST ANSWER

WASD keys for movement

Try this approach (it perfectly works on macOS app but I didn't test it on macCatalyst app):

import SceneKit

class GameViewController: NSViewController {        
    var sceneView = SCNView(frame: .zero)
    let scene = SCNScene(named: "ship.scn")!
    let cameraNode = SCNNode()
    
    override func keyDown(with event: NSEvent) {
        for char in event.characters! {
            switch char {
                case "w" : cameraNode.position.z -= 0.5
                           print("Camera Moves Forward")
                case "s" : cameraNode.position.z += 0.5
                           print("Camera Moves Backward")
                case "a" : cameraNode.position.x -= 0.5
                           print("Camera Moves Left")
                case "d" : cameraNode.position.x += 0.5
                           print("Camera Moves Right")
                default : break
            }
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        sceneView = self.view as! SCNView
        sceneView.scene = scene
        sceneView.allowsCameraControl = false
        
        cameraNode.camera = SCNCamera()
        cameraNode.position.z = 10.0
        sceneView.pointOfView = cameraNode
        sceneView.scene?.rootNode.addChildNode(cameraNode)
    }
}

Also, you can use keyCode instance property:

override func keyDown(with event: NSEvent) {
    
    let code: UInt16 = event.keyCode
    
    if code == 13 {
        cameraNode.position.z -= 0.5; print("Camera Moves Forward")
    } else if code == 1 {
        cameraNode.position.z += 0.5; print("Camera Moves Backward")
    } else if code == 0 {
        cameraNode.position.x -= 0.5; print("Camera Moves Left")
    } else if code == 2 {
        cameraNode.position.x += 0.5; print("Camera Moves Right")
    }
}