SceneKit 3D Programming for iOS: Getting Started

Learn how to use SceneKit for 3D graphics programming by building an app modeling the solar system. By Keegan Rush.

4.9 (13) · 2 Reviews

Download materials
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

Working With the Camera

When you select a different planet in Solar Scenes’ planet switcher, it’d be great if the scene focused on the selected planet. At the moment, SceneKit controls the camera, but you can move it programmatically as well. To focus the camera on the selected planet, you’ll use a constraint.

Using Constraints

Similar to Auto Layout constraints, SceneKit’s SCNConstraint and its subclasses let you specify rules to apply to the position and orientation of any node.

For example, SCNDistanceConstraint can force a node to maintain a specified distance from another node. Using SCNBillboardConstraint, you can force a node to face the camera, like a creepy painting that seems to follow you wherever you stand.

For the selected planet, you’ll use SCNLookAtConstraint to force the camera to look at the selected planet node. To smooth the camera’s change in orientation, you’ll animate it using an action.

Animating With Actions

Actions are a method of performing simple animations. By running an action, a node can smoothly change its position and orientation, scale to a different size and more.

Next, you’ll use an action to animate the camera’s position change when switching planets in Solar Scenes, and you’ll use a constraint to focus on the planet.

Focusing on the Selected Planet

First, add this to ContentView.swift just before the closing brace:

func planetNode(planet: Planet) -> SCNNode? {
  scene?.rootNode.childNode(withName: planet.rawValue, recursively: false)
}

This grabs the planet node corresponding to a Planet model object.

Next, find setUpCamera(planet:). Add this before the return statement at the end:

// 1
if let planetNode = planet.flatMap(planetNode(planet:)) {
  // 2
  let constraint = SCNLookAtConstraint(target: planetNode)
  cameraNode?.constraints = [constraint]
  // 3
  let globalPosition = planetNode
    .convertPosition(SCNVector3(x: 50, y: 10, z: 0), to: nil)
  // 4
  let move = SCNAction.move(to: globalPosition, duration: 1.0)
  cameraNode?.runAction(move)
}

Here’s what’s happening:

  1. ContentView calls setUpCamera(planet:) when setting up the view body, passing the currently selected planet from the view model. Here, you’re getting a reference to that planet’s node using planetNode(planet:).
  2. Create an SCNLookAtConstraint, which focuses on planetNode, then apply it to cameraNode‘s constraints.
  3. Nodes define their own coordinate space. So, use convertPosition(_:to:) to convert a position that’s close to the planet into the same position in the global coordinate space.
  4. Using the global position, create and run an action to update cameraNode‘s position.

Finally, when the camera is focusing on a planet, you should disable SceneKit’s automatic camera control. Go to the initialization of SceneView in body. Find options and replace it with this:

options: viewModel.selectedPlanet == nil ? [.allowsCameraControl] : []

Here, you’re removing automatic control of the camera if you selected a planet.

Build and run. Flip through the planets in the planet switcher and enjoy that smooth animation as the camera focuses on the selected planet.

The completed running app

Great work!

Where to Go From Here?

You can download the final project by using the Download Materials button at the top or bottom of this page.

SceneKit is a powerful, yet accessible, entry point into 3D programming. If you want to learn more about SceneKit, Apple’s documentation and WWDC videos will be your guide.

In this tutorial, you took a simple app and added a fully interactive 3D scene. You made visual representations for planets in the solar system rather than just using a plain old 2D interface.

Next, why not add the missing planets to Solar Scenes? Or, you could bring the scene into the real world by supporting augmented reality. Look at our book, Apple Augmented Reality by Tutorials, to learn how.

If you have questions or comments, or if you’d like to share the cool scenes you’re making in SceneKit, please join the discussion below.