ross dexter, game technologies engineer · • otherwise a default empty node add content as...

98
#WWDC17 © 2017 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple. Ross Dexter, Game Technologies Engineer Going Beyond 2D with SpriteKit Session 609 Graphics and Games

Upload: doandan

Post on 07-Apr-2018

221 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

#WWDC17

© 2017 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.

Ross Dexter, Game Technologies Engineer

•Going Beyond 2D with SpriteKit • Session 609

Graphics and Games

Page 2: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

SpriteKit What is SpriteKit?

2D graphics framework for games

Flexible, fast, easy to use

Supported on iOS, macOS, tvOS, and watchOS

Xcode integrated live editor

Page 3: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

SceneKit SpriteKit

Apple Graphics Frameworks

Metal

App

ARKit

Page 4: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Going Beyond 2D with SpriteKit

•Rendering content in ARKit with SpriteKit •Using SpriteKit and SceneKit in ARKit •Introduction to SKRenderer

Page 5: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

•Working with ARKit

Page 6: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

What is Augmented Reality?

Page 7: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd
Page 8: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

ARKit does all the hard work for you

Tracks your device’s pose

Provide it content you want to appear in AR

Updates the relative position of your content

See Introducing ARKit for more info

Working with ARKit What is ARKit?

Page 9: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit Content anchors

Anchors are what makes AR work

3D points tied to real-world features

ARKit uses device hardware to detect them

Easy to create

Page 10: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit How ARKit works with SpriteKit

ARKit directly interacts with SpriteKit

Asks for nodes it will associate with anchors

Nodes are updated as the device moves

Sprites always face the camera

ARKit

SpriteKit

Page 11: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit How sprites work in 3D

World Camera View

Page 12: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit How sprites work in 3D

World Camera View

Page 13: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit How sprites work in 3D

World Camera View

Page 14: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit How sprites work in 3D

World Camera View

Page 15: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit How sprites work in 3D

World Camera View

Page 16: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit How sprites work in 3D

World Camera View

Page 17: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit How sprites work in 3D

World Camera View

Page 18: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit How sprites work in 3D

World Camera View

Page 19: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit ARKit Objects

ARAnchor

ARSKView

ARSKViewDelegate

ARSession

Page 20: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit ARKit Objects

ARAnchor

ARSKView

ARSKViewDelegate

ARSession

Page 21: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

ARSession The heart of ARKit

Handles device tracking

Orchestrates interactions with SpriteKit

Methods for adding and removing anchors

Call run method to start • Requires an ARSessionConfiguration • Use ARWorldTrackingSessionConfiguration

ARAnchor

ARSKView

ARSKViewDelegate

ARSession

Page 22: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

ARAnchor Defines real-world feature points

Contains transform data, unique identifier

ARAnchors are mapped to SKNodes

ARAnchor

ARSKView

ARSKViewDelegate

ARSession

Page 23: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

ARSKView Bridge between SpriteKit and ARKit

Derived from SKView

Creates and contains ARSession

Methods for getting related anchors/nodes

hitTest method for creating anchors

ARAnchor

ARSKView

ARSKViewDelegate

ARSession

Page 24: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

ARSKViewDelegate Callbacks for anchor updates

Protocol derived from SKViewDelegate

All methods are optional

ARAnchor

ARSKView

ARSKViewDelegate

ARSession

Page 25: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit Creating a project

New AR app template in Xcode 9

Page 26: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit Creating a project

New AR app template in Xcode 9

Select SpriteKit as the content technology

Page 27: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

New AR app template in Xcode 9

Select SpriteKit as the content technology

Ready to enter augmented reality!

Working with ARKit Creating a project

Page 28: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit Scene.sks

The SpriteKit scene

Add non-AR content here • Good for HUD, help text, etc. • Z ≥ 0 will draw over AR content

AR content is managed by ARKit • AR content z positions are < 0

Page 29: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit Scene.swift

The SpriteKit scene’s corresponding source file

Put code to manage your scene in here • Gameplay, logic, etc.

Page 30: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit ViewController.swift

App’s view controller

Conforms to ARSKViewDelegate

ARSKView sceneView property

Primary means of ARKit interaction

Calls run on ARSession

Implement delegate methods here

Page 31: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit Anchor events

Page 32: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit Anchor events

Anchor added

Page 33: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit Anchor events

Anchor added Create AR content

Page 34: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit Anchor events

Anchor added

Anchor updated

Create AR content

Page 35: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit Anchor events

Anchor added

Anchor updated

Create AR content

React to update

Page 36: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit Anchor events

Anchor added

Anchor updated

Anchor removed

Create AR content

React to update

Page 37: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit Anchor events

Anchor added

Anchor updated

Anchor removed

Create AR content

React to update

Perform cleanup

Page 38: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit Anchor events

view(view:nodeFor anchor:)

view(view:didAdd node: for anchor:)

view(view:willUpdate node: for anchor:)

view(view:didUpdate node: for anchor:)

view(view:didRemove node: for anchor:)

Anchor added

Anchor updated

Anchor removed

Page 39: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

ARSKViewDelegate Methods Anchor added

view(view:nodeFor anchor:)

view(view:didAdd node: for anchor:)

view(view:willUpdate node: for anchor:)

view(view:didUpdate node: for anchor:)

view(view:didRemove node: for anchor:)

Create a custom node for an anchor

If not implemented, SKNode created for you

Node will be modified by ARKit

Automatically added to the scene graph

Page 40: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

ARSKViewDelegate Methods Anchor added

Called after an SKNode is mapped to an anchor

If view(view:nodeFor anchor:) implemented • Node is the result of that method • Otherwise a default empty node

Add content as children of node

Children won’t be modified by ARKit

view(view:nodeFor anchor:)

view(view:didAdd node: for anchor:)

view(view:willUpdate node: for anchor:)

view(view:didUpdate node: for anchor:)

view(view:didRemove node: for anchor:)

Page 41: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

ARSKViewDelegate Methods Anchor updated

Called when node is updated with anchor’s data • willUpdate called before update • didUpdate called after update

Occurs when device moves & view changes

Node’s transform may change

view(view:nodeFor anchor:)

view(view:didAdd node: for anchor:)

view(view:willUpdate node: for anchor:)

view(view:didUpdate node: for anchor:)

view(view:didRemove node: for anchor:)

Page 42: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Called when node removed from scene graph

Occurs on anchor removed from ARSession

ARSKViewDelegate Methods Anchor removed

view(view:willUpdate node: for anchor:)

view(view:didUpdate node: for anchor:)

view(view:nodeFor anchor:)

view(view:didAdd node: for anchor:)

view(view:didRemove node: for anchor:)

Page 43: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

// Creating anchors - Scene.swift

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { guard let sceneView = self.view as? ARSKView else { return } if let touchLocation = touches.first?.location(in: sceneView) { // Create anchor with ARSKView’s hitTest method if let hit = sceneView.hitTest(touchLocation, types: .featurePoint).first { sceneView.session.add(anchor: ARAnchor(transform: hit.worldTransform)) } }}

Page 44: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

// Creating anchors - Scene.swift

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { guard let sceneView = self.view as? ARSKView else { return } if let touchLocation = touches.first?.location(in: sceneView) { // Create anchor with ARSKView’s hitTest method if let hit = sceneView.hitTest(touchLocation, types: .featurePoint).first { sceneView.session.add(anchor: ARAnchor(transform: hit.worldTransform)) } }}

Page 45: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

// Creating anchors - Scene.swift

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { guard let sceneView = self.view as? ARSKView else { return } if let touchLocation = touches.first?.location(in: sceneView) { // Create anchor with ARSKView’s hitTest method if let hit = sceneView.hitTest(touchLocation, types: .featurePoint).first { sceneView.session.add(anchor: ARAnchor(transform: hit.worldTransform)) } }}

Page 46: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

// Creating anchors - Scene.swift

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { guard let sceneView = self.view as? ARSKView else { return } if let touchLocation = touches.first?.location(in: sceneView) { // Create anchor with ARSKView’s hitTest method if let hit = sceneView.hitTest(touchLocation, types: .featurePoint).first { sceneView.session.add(anchor: ARAnchor(transform: hit.worldTransform)) } }}

Page 47: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

// Providing SpriteKit content - ViewController.swift

// Implementation of delegate method func view(_ view: ARSKView, didAdd node: SKNode, for anchor: ARAnchor) {

let labelNode = SKLabelNode(text: “👾”)

labelNode.horizontalAlignmentMode = .center labelNode.verticalAlignmentMode = .center

node.addChild(labelNode) }

Page 48: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

// Providing SpriteKit content - ViewController.swift

// Implementation of delegate method func view(_ view: ARSKView, didAdd node: SKNode, for anchor: ARAnchor) {

let labelNode = SKLabelNode(text: “👾”)

labelNode.horizontalAlignmentMode = .center labelNode.verticalAlignmentMode = .center

node.addChild(labelNode) }

Page 49: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

// Providing SpriteKit content - ViewController.swift

// Implementation of delegate method func view(_ view: ARSKView, didAdd node: SKNode, for anchor: ARAnchor) {

let labelNode = SKLabelNode(text: “👾”)

labelNode.horizontalAlignmentMode = .center labelNode.verticalAlignmentMode = .center

node.addChild(labelNode) }

Page 50: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

// Providing SpriteKit content - ViewController.swift

// Implementation of delegate method func view(_ view: ARSKView, didAdd node: SKNode, for anchor: ARAnchor) {

let labelNode = SKLabelNode(text: “👾”)

labelNode.horizontalAlignmentMode = .center labelNode.verticalAlignmentMode = .center

node.addChild(labelNode) }

Page 51: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

•Demo •SpriteKit and ARKit

Page 52: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

NEWAttributed Strings

SKLabelNode now supports attributed strings

Allows you to mix colors, fonts in the same label

Uses NSAttributedString

Set it on the new attributedText property

Page 53: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

NEWAttributed Strings

SKLabelNode now supports attributed strings

Allows you to mix colors, fonts in the same label

Uses NSAttributedString

Set it on the new attributedText property

Page 54: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

NEWSKTransformNode

SKNode already has z rotation

SKTransformNode adds x, y rotation

Rotations apply to all children

Uses orthographic projection

Getters and setters for • Euler angles, rotation matrices, quaternions

Page 55: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

NEWView Debugger Support

View debugging now supports SpriteKit content

Displays full scene graph

Inspect node properties

For more info, see Debugging with Xcode 9

Page 56: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit Takeaways

Quick and easy to get started

ARKit does all the hard work for you

SpriteKit makes rendering AR content a snap

New SpriteKit features give greater flexibility

Page 57: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit Open questions

What if we don’t want billboarded sprites?

What if we want perspective?

What if we want to mix 2D and 3D content in augmented reality?

What if we want to take SpriteKit further into 3D?

Page 58: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

•SceneKit, SpriteKit, and ARKit

Page 59: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

SceneKit, SpriteKit, and ARKit SceneKit and SpriteKit

SceneKit is SpriteKit’s 3D counterpart

Use SpriteKit scenes as material on objects

Allows for 3D transforms and perspective

Mix 2D and 3D content

Page 60: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

SceneKit, SpriteKit, and ARKit ARKit and SceneKit

SceneKit is also integrated with ARKit

Use SceneKit as the content technology

Page 61: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit ARKit API and SceneKit

API is similar by design

ARAnchor

ARSKView

ARSKViewDelegate

ARSession

Page 62: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Working with ARKit ARKit API and SceneKit

API is similar by design

Template creates ARSCNView for you

ViewController is ARSCNViewDelegate ARAnchor

ARSKView

ARSKViewDelegate

ARSession

Page 63: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

SceneKit, SpriteKit, and ARKit SpriteKit content in SceneKit

Normal SpriteKit rendering • Set scene on SKView • Works with UIKit/AppKit to render and display

UIKit/AppKit

SKView

SKScene

Page 64: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

SceneKit, SpriteKit, and ARKit SpriteKit content in SceneKit

Rendering SpriteKit content in SceneKit • Set scene on SCNMaterialProperty • The material works with SceneKit to render

- Uses SceneKit’s Metal command queue • SpriteKit texture mapped onto geometry

SceneKit

SCNMaterialProperty

SKScene

Page 65: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

SceneKit, SpriteKit, and ARKit SpriteKit content in SceneKit

Page 66: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

SceneKit, SpriteKit, and ARKit SpriteKit content in SceneKit

Page 67: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

SceneKit, SpriteKit, and ARKit SpriteKit content in SceneKit

Page 68: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

SceneKit, SpriteKit, and ARKit SpriteKit content in SceneKit

Page 69: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

// Using SpriteKit in SceneKit

// Get SpriteKit scene let spriteKitScene = SKScene(fileNamed: "SpriteKitScene") // Create plane geometry let plane = SCNPlane(width: 10.0, height: 10.0) // Set SpriteKit scene on the plane's material plane.firstMaterial?.diffuse.contents = spriteKitScene

// If material double-sided, SpriteKit scene will show up on both sides of the plane plane.firstMaterial?.isDoubleSided = true // Create a SceneKit node for the plane let sceneKitNode = SCNNode(geometry: plane) // Add the SceneKit node to the SceneKit scene scene.rootNode.addChildNode(sceneKitNode)

Page 70: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

// Using SpriteKit in SceneKit

// Get SpriteKit scene let spriteKitScene = SKScene(fileNamed: "SpriteKitScene") // Create plane geometry let plane = SCNPlane(width: 10.0, height: 10.0) // Set SpriteKit scene on the plane's material plane.firstMaterial?.diffuse.contents = spriteKitScene

// If material double-sided, SpriteKit scene will show up on both sides of the plane plane.firstMaterial?.isDoubleSided = true // Create a SceneKit node for the plane let sceneKitNode = SCNNode(geometry: plane) // Add the SceneKit node to the SceneKit scene scene.rootNode.addChildNode(sceneKitNode)

Page 71: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

// Using SpriteKit in SceneKit

// Get SpriteKit scene let spriteKitScene = SKScene(fileNamed: "SpriteKitScene") // Create plane geometry let plane = SCNPlane(width: 10.0, height: 10.0) // Set SpriteKit scene on the plane's material plane.firstMaterial?.diffuse.contents = spriteKitScene

// If material double-sided, SpriteKit scene will show up on both sides of the plane plane.firstMaterial?.isDoubleSided = true // Create a SceneKit node for the plane let sceneKitNode = SCNNode(geometry: plane) // Add the SceneKit node to the SceneKit scene scene.rootNode.addChildNode(sceneKitNode)

Page 72: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

// Using SpriteKit in SceneKit

// Get SpriteKit scene let spriteKitScene = SKScene(fileNamed: "SpriteKitScene") // Create plane geometry let plane = SCNPlane(width: 10.0, height: 10.0) // Set SpriteKit scene on the plane's material plane.firstMaterial?.diffuse.contents = spriteKitScene

// If material double-sided, SpriteKit scene will show up on both sides of the plane plane.firstMaterial?.isDoubleSided = true // Create a SceneKit node for the plane let sceneKitNode = SCNNode(geometry: plane) // Add the SceneKit node to the SceneKit scene scene.rootNode.addChildNode(sceneKitNode)

Page 73: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

// Using SpriteKit in SceneKit

// Get SpriteKit scene let spriteKitScene = SKScene(fileNamed: "SpriteKitScene") // Create plane geometry let plane = SCNPlane(width: 10.0, height: 10.0) // Set SpriteKit scene on the plane's material plane.firstMaterial?.diffuse.contents = spriteKitScene

// If material double-sided, SpriteKit scene will show up on both sides of the plane plane.firstMaterial?.isDoubleSided = true // Create a SceneKit node for the plane let sceneKitNode = SCNNode(geometry: plane) // Add the SceneKit node to the SceneKit scene scene.rootNode.addChildNode(sceneKitNode)

Page 74: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

// Using SpriteKit in SceneKit

// Get SpriteKit scene let spriteKitScene = SKScene(fileNamed: "SpriteKitScene") // Create plane geometry let plane = SCNPlane(width: 10.0, height: 10.0) // Set SpriteKit scene on the plane's material plane.firstMaterial?.diffuse.contents = spriteKitScene

// If material double-sided, SpriteKit scene will show up on both sides of the plane plane.firstMaterial?.isDoubleSided = true // Create a SceneKit node for the plane let sceneKitNode = SCNNode(geometry: plane) // Add the SceneKit node to the SceneKit scene scene.rootNode.addChildNode(sceneKitNode)

Page 75: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

// Using SpriteKit in SceneKit

// Get SpriteKit scene let spriteKitScene = SKScene(fileNamed: "SpriteKitScene") // Create plane geometry let plane = SCNPlane(width: 10.0, height: 10.0) // Set SpriteKit scene on the plane's material plane.firstMaterial?.diffuse.contents = spriteKitScene

// If material double-sided, SpriteKit scene will show up on both sides of the plane plane.firstMaterial?.isDoubleSided = true // Create a SceneKit node for the plane let sceneKitNode = SCNNode(geometry: plane) // Add the SceneKit node to the SceneKit scene scene.rootNode.addChildNode(sceneKitNode)

Page 76: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

•Demo •ARKit with SceneKit and SpriteKit

Page 77: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

SceneKit, SpriteKit, and ARKit Takeaways

Allows for full 3D transforms, perspective

Can mix 2D and 3D content

Works with ARKit, or in general 3D apps

Page 78: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

•Introduction to SKRenderer

Page 79: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

How SpriteKit Works Normal usage

UIKit/AppKit

SKView

SKScene

Page 80: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

How SpriteKit Works SpriteKit with SceneKit

UIKit/AppKit

SKView

SKScene

SceneKit

SCNMaterialProperty

SKScene

Page 81: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

NEWHow SpriteKit Works SKRenderer

Metal

SKRenderer

SKScene

UIKit/AppKit

SKView

SKScene

SceneKit

SCNMaterialProperty

SKScene

Page 82: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Introduction to SKRenderer Control update and render

NEW

Use instead of SKView

Control update and render

Works directly with Metal

SceneKit uses to render SpriteKit content

Metal

SKRenderer

SKScene

Page 83: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Introduction to SKRenderer Using SKRenderer

Set SceneInitialize Update Render

Page 84: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

var device: MTLDevice! = nil var renderer: SKRenderer! = nil var skScene: SKScene! = nil var commandQueue: MTLCommandQueue! = nil

device = MTLCreateSystemDefaultDevice() commandQueue = device.makeCommandQueue() renderer = SKRenderer(device: device)

Introduction to SKRenderer Initialization

UpdateSet SceneInitialize Render

Page 85: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

if let scene = SKScene(fileNamed: "GameScene") { skScene = scene renderer.scene = skScene }

UpdateSet SceneInitialize Render

Introduction to SKRenderer Setting the scene

Page 86: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

let currentTime = CACurrentMediaTime() renderer.update(atTime: currentTime)

Introduction to SKRenderer Updating

UpdateSet SceneInitialize Render

Page 87: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

// Render for command buffer renderer.render(withViewport: viewport, commandBuffer: commandBuffer, renderPassDescriptor: renderPassDesc)

// Render for command encoder renderer.render(withViewport: viewport, renderCommandEncoder: renderCommandEncoder, renderPassDescriptor: renderPassDesc, commandQueue: commandQueue)

Introduction to SKRenderer Rendering

UpdateSet SceneInitialize Render

Page 88: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

// Render for command buffer renderer.render(withViewport: viewport, commandBuffer: commandBuffer, renderPassDescriptor: renderPassDesc)

// Render for command encoder renderer.render(withViewport: viewport, renderCommandEncoder: renderCommandEncoder, renderPassDescriptor: renderPassDesc, commandQueue: commandQueue)

Introduction to SKRenderer Rendering

UpdateSet SceneInitialize Render

Page 89: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Introduction to SKRenderer Rendering

UpdateSet SceneInitialize Render

// Render for command buffer renderer.render(withViewport: viewport, commandBuffer: commandBuffer, renderPassDescriptor: renderPassDesc)

// Render for command encoder renderer.render(withViewport: viewport, renderCommandEncoder: renderCommandEncoder, renderPassDescriptor: renderPassDesc, commandQueue: commandQueue)

Page 90: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Introduction to SKRenderer Rendering

UpdateSet SceneInitialize Render

// Render for command buffer renderer.render(withViewport: viewport, commandBuffer: commandBuffer, renderPassDescriptor: renderPassDesc)

// Render for command encoder renderer.render(withViewport: viewport, renderCommandEncoder: renderCommandEncoder, renderPassDescriptor: renderPassDesc, commandQueue: commandQueue)

Page 91: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Introduction to SKRenderer Rendering

UpdateSet SceneInitialize Render

// Render for command buffer renderer.render(withViewport: viewport, commandBuffer: commandBuffer, renderPassDescriptor: renderPassDesc)

// Render for command encoder renderer.render(withViewport: viewport, renderCommandEncoder: renderCommandEncoder, renderPassDescriptor: renderPassDesc, commandQueue: commandQueue)

Page 92: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

•Demo •Drawing SpriteKit content in 3D with Metal

Page 93: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Introduction to SKRenderer Takeaways

SKRenderer gives more control over SpriteKit

Update and render exactly when you want

Use with Metal however you see fit

Page 94: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Summary

SpriteKit is useful in both 2D and 3D

Plays nice with SceneKit, Metal, and ARKit

New features give you more control than ever

Page 95: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

More Informationhttps://developer.apple.com/wwdc17/609

Page 96: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Related Sessions

Introducing Metal 2 Executive Ballroom Tuesday 1:50PM

Introducing ARKit: Augmented Reality for iOS Hall 3 Tuesday 5:10PM

SceneKit: What’s New Grand Ballroom A Wednesday 11:00AM

Debugging with Xcode 9 Hall 2 Wednesday 10:00AM

Page 97: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd

Labs

GameplayKit Lab Technology Lab G Fri 9:00AM–12:00PM

SpriteKit Lab Technology Lab G Fri 12:00PM–2:30PM

Page 98: Ross Dexter, Game Technologies Engineer · • Otherwise a default empty node Add content as children of node Children won’t be modified by ARKit view(view:nodeFor anchor:) view(view:didAdd