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面にどういう順番で貼り付けられるのか、シミューレータを動かして、よく確認しましょう。
時間ができたら、Scene Kit初学者向けの小ネタを、載せていこうかなと、考えています。