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

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

```swift: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](https://qiita-image-store.s3.amazonaws.com/0/83254/0d0c7f96-d534-ca44-dbfa-71013585aa78.png)

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