SceneKit Tutorial With Swift Part 2: Nodes
In the second installment of our SceneKit With Swift tutorial, you’ll dive into coding your first 3D iOS game, Geometry Fighter, by learning about nodes. By Chris Language.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
SceneKit Tutorial With Swift Part 2: Nodes
25 mins
- Getting Started
- Asset Catalogs
- Adding an Asset Catalog
- Adding a Launch Screen
- Adding a Background Image
- The SceneKit Coordinate System
- Cameras
- Adding a Camera
- Geometry
- Adding ShapeTypes
- Adding a Geometry Node
- Built-in View Features
- Working with Scene Statistics
- Challenges
- Your First Challenge
- Where to Go From Here?
Adding a Geometry Node
Your next task is to create a method that spawns the various random shapes defined in ShapeType.
Add the following method to GameViewController.swift, right below setupCamera()
:
func spawnShape() {
// 1
var geometry:SCNGeometry
// 2
switch ShapeType.random() {
default:
// 3
geometry = SCNBox(width: 1.0, height: 1.0, length: 1.0,
chamferRadius: 0.0)
}
// 4
let geometryNode = SCNNode(geometry: geometry)
// 5
scnScene.rootNode.addChildNode(geometryNode)
}
Taking each numbered comment in turn:
-
First, you create a placeholder
geometry
variable for use a bit later on. -
Next, you define a
switch
statement to handle the returned shape fromShapeType.random()
. It’s incomplete at the moment, and only creates a box shape; you’ll add more to it in the challenge at the end of this tutorial. -
Then, you create an
SCNBox
object and store it ingeometry
. You specify the width, height and length, along with the chamfer radius (which is a fancy way of saying rounded corners). -
Here, you create an instance of
SCNNode
namedgeometryNode
. This time, you make use of theSCNNode
initializer which takes ageometry
parameter to create a node and automatically attach the supplied geometry. - Finally, you add the node as a child of the scene’s root node.
Now you need to call this method. Add the following line to viewDidLoad()
below setupCamera()
:
spawnShape()
Build and run; you’ll see a white square displayed onscreen:
There are a few things to observe here:
-
The box node is the default shape from
spawnShape()
, and it sits at(x:0, y:0, z:0)
in the scene. -
You’re viewing the scene through your
cameraNode
. Since the camera node lives at(x:0, y:0: z:10)
, the box is smack dab in the center of the camera’s viewable area.
OK, it’s not very exciting, and it’s hardly three-dimensional — but fear not… the next section changes all of that!
Built-in View Features
SCNView
comes with a few out-of-the-box features to help make your life easier.
Add the following lines to setupView()
in GameViewController.swift, just below the current implementation:
// 1
scnView.showsStatistics = true
// 2
scnView.allowsCameraControl = true
// 3
scnView.autoenablesDefaultLighting = true
Here’s an explanation of the code above:
-
showStatistics
enables a real-time statistics panel at the bottom of your scene. -
allowsCameraControl
lets you manually control the active camera through simple gestures. -
autoenablesDefaultLighting
creates a generic omnidirectional light in your scene so you don’t have to worry about adding your own light sources.
Build and run; things should look a little more exciting this time around!
You can use the following gestures to control the active camera in your scene:
- Single finger swipe: Rotates your active camera around the contents of the scene.
- Two finger swipe: Moves, or pans your camera left, right, up or down in the scene.
- Two finger pinch: Zooms the camera in and out of the scene.
- Double-tap: If you have more than one camera, this switches between the cameras in your scene. Of course, since you have only one camera in the scene, this doesn’t do that. However, it also has the effect of resetting the camera to its original position and settings.
Working with Scene Statistics
Find the statistics panel at the bottom of the screen:
Here’s a quick breakdown of what each element means:
- fps: Stands for frames per second. This a measurement of the total amount of consecutive frame redraws done in one-second. The lower this amount, the more poorly your game is performing. You typically want your game to run at 60fps, which will make your game look and feel smooth.
- ◆: Stands for total draw calls per frame. This is typically the total amount of visible objects drawn per single frame. Lights affecting objects can also increase the amount of draw calls of an object. The lower this amount, the better.
- ▲: Stands for total polygons per frame. This the total amount of polygons used to draw a single frame for all the visible geometry. The lower this amount, the better.
- ✸: Stands for total visible light sources. This is the total amount of light sources currently affecting visible objects. The SceneKit guidelines recommend not using more than 3 light sources at a time.
Click on the + button to expand the panel and reveal more detail:
This panel provides you with the following information:
- Frame time: This is the total amount of time it took to draw a single frame. A frame time of 16.7ms is required to achieve a frame rate of 60fps.
- The color chart: This provides you with a rough frame time percentage breakdown per component within the SceneKit rendering pipeline.
From this example, you now know that it took 22.3ms to draw a single frame of which ±75% was used for Rendering, and ±25% was used for GL Flush.
You can click the – button to minimize the panel again.
Isn’t it great that all these features are built-in? :]
Challenges
It’s important for you to practice what you’ve learned, on your own, so many parts of this series have one or more challenges associated with them.
I highly recommend trying all of the challenges. While following a step-by-step tutorial is educational, you’ll learn a lot more by solving a problem by yourself.
If you get stuck, you can find solutions in the resources for the tutorial — but to get the most from this series, give it your best shot before you look!
Your First Challenge
There’s only one challenge in this tutorial, but it’s a fun one.
Your challenge is to improve the switch
statement inside spawnShape()
to handle the remaining shapes in the enumerator.
Use Apple’s official SceneKit documentation (http://apple.co/2aDBgtH) as a guide to the various geometric shapes. Also, take a look at the ShapeType
enum to see which shapes are left to create; their names should give you a good idea of where to start.
Don’t worry too much about the sizes to use; just try to make them about the same relative size as the box you made earlier.
After this challenge, you’ll have a firm grasp on some of the most fundamental concepts in SceneKit! :]