Posted at

Swift2.2 Scene Kitの超シンプル、サンプルコード

More than 3 years have passed since last update.

Xcode 7にある、Scene Kitのテンプレート(宇宙船がクルクル回る、アレ)を、すこし書き換えて、オブジェクトをSceneファイルからでなく、プログラムで作るようにしました。Scene Kit初学者のみなさんには、こちらのほうが参考になるかなと思います。


GameViewController.swift

import UIKit

import SceneKit

class GameViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

// create a new scene
let scene = SCNScene()

// create and add a camera to the scene
let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
scene.rootNode.addChildNode(cameraNode)

// place the camera
cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)

// create and add a light to the scene
let lightNode = SCNNode()
lightNode.light = SCNLight()
lightNode.light!.type = SCNLightTypeOmni
lightNode.position = SCNVector3(x: 0, y: 10, z: 10)
scene.rootNode.addChildNode(lightNode)

// create and add an ambient light to the scene
let ambientLightNode = SCNNode()
ambientLightNode.light = SCNLight()
ambientLightNode.light!.type = SCNLightTypeAmbient
ambientLightNode.light!.color = UIColor.darkGrayColor()
scene.rootNode.addChildNode(ambientLightNode)

// create a cube node
let cubeGeometry = SCNBox(width: 2.0, height: 2.0, length: 2.0, chamferRadius: 0.0)
// create cube textures
if let frontImage = UIImage(named: "front"),
let backImage = UIImage(named: "back"),
let leftImage = UIImage(named: "left"),
let rightImage = UIImage(named: "right"),
let topImage = UIImage(named: "top"),
let bottomImage = UIImage(named: "bottom") {
let frontMaterial = SCNMaterial()
frontMaterial.diffuse.contents = frontImage
let backMaterial = SCNMaterial()
backMaterial.diffuse.contents = backImage
let leftMaterial = SCNMaterial()
leftMaterial.diffuse.contents = leftImage
let rightMaterial = SCNMaterial()
rightMaterial.diffuse.contents = rightImage
let topMaterial = SCNMaterial()
topMaterial.diffuse.contents = topImage
let bottomMaterial = SCNMaterial()
bottomMaterial.diffuse.contents = bottomImage

cubeGeometry.materials = [frontMaterial, rightMaterial, backMaterial, leftMaterial, topMaterial, bottomMaterial]
}
let cubeNode = SCNNode(geometry: cubeGeometry)
cubeNode.position = SCNVector3(x: 0, y: 0, z: 0)
scene.rootNode.addChildNode(cubeNode)

// animate the 3d object
cubeNode.runAction(SCNAction.repeatActionForever(SCNAction.rotateByX(0, y: 2, z: 0, duration: 1)))

// retrieve the SCNView
let scnView = self.view as! SCNView

// set the scene to the view
scnView.scene = scene

// allows the user to manipulate the camera
scnView.allowsCameraControl = true

// show statistics such as fps and timing information
scnView.showsStatistics = true

// configure the view
scnView.backgroundColor = UIColor.blackColor()

// add a tap gesture recognizer
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
scnView.addGestureRecognizer(tapGesture)
}

func handleTap(gestureRecognize: UIGestureRecognizer) {
// retrieve the SCNView
let scnView = self.view as! SCNView

// check what nodes are tapped
let p = gestureRecognize.locationInView(scnView)
let hitResults = scnView.hitTest(p, options: nil)
// check that we clicked on at least one object
if hitResults.count > 0 {
// retrieved the first clicked object
let result: AnyObject! = hitResults[0]

// get its material
let material = result.node!.geometry!.firstMaterial!

// highlight it
SCNTransaction.begin()
SCNTransaction.setAnimationDuration(0.5)

// on completion - unhighlight
SCNTransaction.setCompletionBlock {
SCNTransaction.begin()
SCNTransaction.setAnimationDuration(0.5)

material.emission.contents = UIColor.blackColor()

SCNTransaction.commit()
}

material.emission.contents = UIColor.redColor()

SCNTransaction.commit()
}
}

override func shouldAutorotate() -> Bool {
return true
}

override func prefersStatusBarHidden() -> Bool {
return true
}

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
return .AllButUpsideDown
} else {
return .All
}
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}

}


プログラムで作成するオブジェクトは、立方体SCNBoxです。テクスチャとして6枚のイメージを貼り付けています。テクスチャSCNMaterialの貼り付け方は、最初につまづきやすいところではないかなと思います。6つのイメージが、6面にどういう順番で貼り付けられるのか、シミューレータを動かして、よく確認しましょう。

Simulator Screen Shot 2016.06.13 17.04.14.png

時間ができたら、Scene Kit初学者向けの小ネタを、載せていこうかなと、考えています。