scaling a SCNNode in runtime using the Pinch gesture

Viewed 2544

I am trying to scale and SCNNode in real time using the Pinch gesture:

This is my current code

let pinchGestureRecognizer = UIPinchGestureRecognizer(target: self, action: #selector(handlePinch(from:)))
sceneView.addGestureRecognizer(pinchGestureRecognizer)

@objc
func handlePinch(from recognizer: UIPinchGestureRecognizer){
  var pinchScale = recognizer.scale
  pinchScale = round(pinchScale * 1000) / 1000.0

  sceneView.scene.rootNode.enumerateChildNodes { (node, stop) -> Void in
    if(node.name == "Box01"){
       node.scale = SCNVector3(x: pinchScale, y: pinchScale, z: pinchScale)
    }
  }        
}

However the node doesn't scale big or small? Can someone please point my mistake?

The SCNNode is loaded and has an animation on applied like so,

sceneView.scene.rootNode.addChildNode(node)
loadAnimation(animation: .Attack, sceneName: "art.scnassets/attack", animationIdentifier: "attackID");
5 Answers

Got it to work in swift

@objc func handlePinch(gesture: UIPinchGestureRecognizer){
    if(scnnodeSelected){

        if (gesture.state == .changed) {
            let pinchScaleX = Float(gesture.scale) * tappedObjectNode.scale.x
            let pinchScaleY =  Float(gesture.scale) * tappedObjectNode.scale.y
            let pinchScaleZ =  Float(gesture.scale) * tappedObjectNode.scale.z
            tappedObjectNode.scale = SCNVector3(pinchScaleX, pinchScaleY, pinchScaleZ)
            gesture.scale=1
        }
    }
}
func addPinchGestureToSceneView(){
    let pinchGestureRecognizer = UIPinchGestureRecognizer(target: self, action: #selector(ViewController.handlePitch(withGestureRecognizer:)))
    sceneView.addGestureRecognizer(pinchGestureRecognizer)
}


@objc func handlePitch(withGestureRecognizer recognizer: UIPinchGestureRecognizer) {
    let tapRecognizer = recognizer.location(in: sceneView)
    let hitTestResults = sceneView.hitTest(tapRecognizer)
    guard let node = hitTestResults.first?.node else {
        return
    }

    if (recognizer.state == .changed) {
        let pinchScaleX = Float(recognizer.scale) * node.scale.x
        let pinchScaleY =  Float(recognizer.scale) * node.scale.y
        let pinchScaleZ =  Float(recognizer.scale) * node.scale.z

        node.scale = SCNVector3(x: Float(pinchScaleX), y: Float(pinchScaleY), z: Float(pinchScaleZ))
        recognizer.scale=1
    }

}

Update for Swift 5 :

@objc func handlePinch(_ gesture: UIPinchGestureRecognizer) {
    if (gesture.state == .changed) {
        yourSKNode.xScale *= gesture.scale
        yourSKNode.yScale *= gesture.scale
        gesture.scale = 1
    }
}

and my didMove function :

override func didMove(to view: SKView) {
    super.didMove(to: view)
    setupNodes()

    self.view!.addGestureRecognizer(UIPinchGestureRecognizer(target: self, action: #selector(handlePinch(_:))))
}
Related