swiftmacosscenekitskactionskcameranode

spritekit how to selectively scale nodes


as background lets assume I have a map- literally a road map being rendered inside my SKScene. Roads are represented by SKShapenodes with path set to an array of CGPoints. I want the user to be able to zoom in/out so I created a camera node:

var cam: SKCameraNode = SKCameraNode()

and as the user wants to zoom in/out by scrolling on the trackpad:

let zoomInAction = SKAction.scale(to: CGFloat(scale), duration: 0.0)
camera?.run(zoomInAction)

This works great however I have an additional complexity which I'm not sure how to handle. I want some nodes (for examples road name labels, icons, map legend) to be exempt from scaling- such that as a user zooms in/out the road name label remains the same size while the road shape scales proportionally.

Not sure how to handle this? Can I have a hierarchy of scenes so one layer scales and the other doesnt scale? Can that be achieved by attaching the camera node to the "scalable" layer? Any help appreciated!


Solution

  • Here is the case. If you want the node scale won't change with camera, just add the node to the tree of camera. Don't forget add cameraNode to scene, otherwise, those nodes connected to camera won't be rendered.

    In the following, label is rendered via camera and won't change scale.

                let  label =   SKLabelNode.init(text: "GFFFGGG")
                label.fontSize = 30
                label.fontColor = UIColor.black
                label.name = "cool"
                label.zPosition = 100
    
                let camera = SKCameraNode()
                camera.addChild(label)
    
                scene.addChild(camera)
                scene.camera = camera
    
             camera.position = CGPoint.init(x: 0, y: 0)
                camera.xScale = 2.0
    

    If you have nodes connecting to scene before, you may remove the node from parent and then add to camera.
    If using a function to batch handling them should not be as hard as thought.

    Maybe not necessary:

    You may transfer them to cameraNode tree via camera.convert(point: , from:) etc.