LoginSignup
11
10

More than 5 years have passed since last update.

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

Posted at

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初学者向けの小ネタを、載せていこうかなと、考えています。

11
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
10