A node that renders a Scene Kit scene as a 2D image.


class SK3DNode : SKNode


Use SK3DNode objects to incorporate 3D SceneKit content into a SpriteKit-based game. When SpriteKit renders the node, the SceneKit scene is animated and rendered first. Then this rendered image is composited into the SpriteKit scene. Use the scnScene property to specify the SceneKit scene to be rendered.

SceneKit content rendered in SpriteKit is automatically assigned a camera and, since autoenablesDefaultLighting defaults to true, lights. That means you require very little code to add simple 3D primitives to your scene. Listing 1 shows how to create a simple scene containing a torus and display it in a SpriteKit scene.

Listing 1

Rendering SceneKit content in a SpriteKit node

let scnScene: SCNScene = {
    let scnScene = SCNScene()
    let torusGeometry = SCNTorus(ringRadius: 10, pipeRadius: 3)
    let torusNode = SCNNode(geometry: torusGeometry)
    torusNode.eulerAngles = SCNVector3(x: CGFloat.pi / 2, y: 0, z: 0)
    return scnScene
let node = SK3DNode(viewportSize: CGSize(width: 200, height: 200))
node.scnScene = scnScene

After node is added to a SKScene, the 3D torus is visible:

Figure 1

SceneKit torus rendered in SpriteKit

SceneKit torus rendered in SpriteKit

Although SK3DNode creates a default camera automatically, you can create your own camera for precise control over how the 3D content is rendered. Listing 2 shows how you can create a 3D node with an explicitly created camera that looks at the first object in the SceneKit scene's node tree.

Listing 2

Creating an explicit camera

let node = SK3DNode(viewportSize: CGSize(width: 200, height: 200))
node.position = position
node.scnScene = scnScene = "3dnode"
let camera = SCNCamera()
let cameraNode = SCNNode() = camera
if let lookAtTarget = scnScene.rootNode.childNodes.first {
    let constraint = SCNLookAtConstraint(target: lookAtTarget)
    cameraNode.constraints = [ constraint ]
node.pointOfView = cameraNode
node.pointOfView?.position = SCNVector3(x: 0, y: 0, z: 20)

You can create many instances of SK3DNode each sharing the same SceneKit scene but each with an independent point of view. By updating the position of each 3D node's point of view, you can create code that simulates a top-down, one-point perspective view. Listing 3 shows a example of how to do this by enumerating over all the nodes named 3dnode in the update method of a SKSceneDelegate.

scene.enumerateChildNodes(withName: "3dnode") {
    node, _ in
    if let node = node as? SK3DNode {
        let positionX = (width * 0.5 - node.position.x) / 10
        let positionY = (height * 0.5 - node.position.y) / 10
        node.pointOfView?.position = SCNVector3(x: positionX, y: positionY, z: 20)

Figure 2 illustrates how this code gives the impression of perspective inside SpriteKit:

Figure 2

Top down perspective using SK3DNode

Top down perspective using SK3DNode


Creating a 3D Node

init(viewportSize: CGSize)

Initializes a new 3D node.

Configuring the 3D Node

var viewportSize: CGSize

The size of the image rendered by the node.

var scnScene: SCNScene?

The SceneKit scene to render.

var pointOfView: SCNNode?

The Scene Kit node from which the scene’s contents are viewed when rendered.

var autoenablesDefaultLighting: Bool

A Boolean value that determines whether Scene Kit automatically adds lights to a scene.

Animating the 3D Node’s Content in Scene Kit

var isPlaying: Bool

A Boolean value that determines whether the scene is playing.

var loops: Bool

A Boolean value that determines whether Scene Kit restarts the scene time after all animations in the scene have played.

var sceneTime: TimeInterval

The current scene time.

Projecting and Hit Testing

func hitTest(CGPoint, options: [String : Any]? = nil) -> [SCNHitTestResult]

Searches the Scene Kit scene for objects corresponding to a point in the rendered image.

func projectPoint(vector_float3) -> vector_float3

Projects a point from the 3D world coordinate system of the SceneKit scene to the 2D viewport coordinate system of the SpriteKit node.

func unprojectPoint(vector_float3) -> vector_float3

Unprojects a point from the SpriteKit node’s 2D viewport coordinate system to the 3D world coordinate system of the SceneKit scene.

See Also

Integrating with Other Frameworks

class SKEffectNode

A node that can apply Core Image filters or SKWarpGeometry distortions to its children.