Search code examples
swiftscenekit

swift SceneKit decline node move


I create a sphere node, I need the user to be able only to rotate (left / right, up / down) and zoom in / out the node, but default he can move the node from the center (with two fingers) - is possible prohibit the user to move the node from the center? thanks for any help

sceneView.scene = scene

cameraOrbit = SCNNode()
cameraNode = SCNNode()
camera = SCNCamera()

// camera stuff
camera.usesOrthographicProjection = true
camera.orthographicScale = 5
camera.zNear = 1
camera.zFar = 100

cameraNode.position = SCNVector3(x: 0, y: 0, z: 70)
cameraNode.camera = camera
cameraOrbit = SCNNode()
cameraOrbit.addChildNode(cameraNode)
scene.rootNode.addChildNode(cameraNode)

let sphere = SCNSphere(radius: 2)
sphere.firstMaterial?.diffuse.contents = UIColor.red
let earthNode = SCNNode(geometry: sphere)
earthNode.name = "sphere"
earthNode.geometry?.materials = [blueMaterial]
scene.rootNode.addChildNode(earthNode)
earthNode.rotation = SCNVector4(0, 1, 0, 0)

let lightNode = SCNNode()
let light = SCNLight()
light.type = .ambient
light.intensity = 200
lightNode.light = light
scene.rootNode.addChildNode(lightNode)

sceneView.allowsCameraControl = true
sceneView.backgroundColor = UIColor.clear
sceneView.cameraControlConfiguration.allowsTranslation = true
sceneView.cameraControlConfiguration.rotationSensitivity = 0.4

Solution

  • You can put similar code into your UIViewController:

    //**************************************************************************
        // Gesture Recognizers
        // MARK: Gesture Recognizers
        //**************************************************************************
        @objc func handleTap(recognizer: UITapGestureRecognizer)
        {
            if(data.isNavigationOff == true) { return }         // No panel select if Add, Update, EndWave, or EndGame
            if(gameMenuTableView.isHidden == false) { return }  // No panel if game menu is showing
            
            let location: CGPoint = recognizer.location(in: gameScene)
            
            if(data.isAirStrikeModeOn == true)
            {
                let projectedPoint = gameScene.projectPoint(SCNVector3(0, 0, 0))
                let scenePoint = gameScene.unprojectPoint(SCNVector3(location.x, location.y, CGFloat(projectedPoint.z)))
                gameControl.airStrike(position: scenePoint)
            }
            else
            {
                let hitResults = gameScene.hitTest(location, options: hitTestOptions)
                for vHit in hitResults
                {
                    if(vHit.node.name?.prefix(5) == "Panel")
                    {
                        // May have selected an invalid panel or auto upgrade was on
                        if(gameControl.selectPanel(vPanel: vHit.node.name!) == false) { return }
                        return
                    }
                }
            }
        }
        //**************************************************************************
        @objc func handlePan(recognizer: UIPanGestureRecognizer)
        {
            if(data.gameState != .run || data.isGamePaused == true) { return }
            
            currentLocation = recognizer.location(in: gameScene)
            
            switch recognizer.state
            {
            case UIGestureRecognizer.State.began:
                beginLocation = recognizer.location(in: gameScene)
                break
            case UIGestureRecognizer.State.changed:
                if(currentLocation.x > beginLocation.x * 1.1)
                {
                    beginLocation.x = currentLocation.x
                    gNodes.camera.strafeLeft()
                }
                if(currentLocation.x < beginLocation.x * 0.9)
                {
                    beginLocation.x = currentLocation.x
                    gNodes.camera.strafeRight()
                }
                break
            case UIGestureRecognizer.State.ended:
                break
            default:
                break
            }
        }