9

I can't seem to find anywhere how to implement a camera pinch to zoom in SpriteKit.

In my GameScene I can seem to run a zoom in action on the camera with:

let cameraNode = SKCameraNode()

cameraNode.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
addChild(cameraNode)
camera = cameraNode

let zoomInAction = SKAction.scale(to: 0.5, duration: 1)
cameraNode.run(zoomInAction)

But I can't seem to figure out how to translate this to a pinch to zoom feature

Brejuro
  • 3,421
  • 8
  • 34
  • 61

1 Answers1

17

Here is a solution that worked for me, using gesture recognizers:

class GameScene: SKScene {

  var previousCameraScale = CGFloat()

  override func sceneDidLoad() {
    let pinchGesture = UIPinchGestureRecognizer()
    pinchGesture.addTarget(self, action: #selector(pinchGestureAction(_:)))
    view?.addGestureRecognizer(pinchGesture)
  }

  @objc func pinchGestureAction(_ sender: UIPinchGestureRecognizer) {
    guard let camera = self.camera else {
      return
    }
    if sender.state == .began {
      previousCameraScale = camera.xScale
    }
    camera.setScale(previousCameraScale * 1 / sender.scale)
  }

}

You can easily define a min and a max for the camera scale, and use your bounds on the calculous if needed.

Steve G.
  • 589
  • 5
  • 13
  • This answer is buggy. After few iterations `previousCameraScale` will reach infinity. – kelin Oct 28 '21 at 10:47
  • I never had this problem, but as I said, I added boundaries to the camera scale, because I didn't want to allow an unlimited zoom. Also, as `previousCameraScale` is only set on the `.began` state, I don't see how it could reach infinity... If you find out, I'll be happy to know it. – Steve G. Oct 29 '21 at 11:19
  • 1
    I found out that you are right. – kelin Oct 29 '21 at 12:01