![]()
赤いライトが出ているところに箱を移動させると大きくなるiPhoneアプリのサンプルコードを描いてみます。
import UIKit
import SceneKit
class ViewController: UIViewController, SCNSceneRendererDelegate {
weak var sceneView : SCNView?
override func viewDidLoad() {
super.viewDidLoad()
setupScene()
createMap()
createBox()
createCamera()
}
func setupScene() {
let sv = SCNView(frame: view.bounds)
sv.backgroundColor = UIColor(hue: 0.05, saturation: 0.2, brightness: 1, alpha: 1)
sv.scene = SCNScene()
sv.allowsCameraControl = true
sv.autoenablesDefaultLighting = true
sv.delegate = self
view.addSubview(sv)
sceneView = sv
}
func createMap() {
let ground = SCNBox(width: 10, height: 1, length: 10, chamferRadius: 0);
ground.firstMaterial?.diffuse.contents = UIColor.brownColor()
let groundNode = SCNNode(geometry: ground)
groundNode.name = “ground”
sceneView?.scene?.rootNode.addChildNode(groundNode)
let plate = SCNCylinder(radius: 1, height: 0.1)
plate.firstMaterial?.diffuse.contents = UIColor.greenColor()
let plateNode = SCNNode(geometry: plate)
plateNode.position = SCNVector3(x: 2, y: 0.5, z: 0)
plateNode.name = “plate”
sceneView?.scene?.rootNode.addChildNode(plateNode)
[Int](0…3).each { i in
let light = SCNTorus(ringRadius: 1, pipeRadius: 0.05)
light.firstMaterial?.diffuse.contents = UIColor.redColor().colorWithAlphaComponent(0.5)
let lightNode = SCNNode(geometry: light)
lightNode.position = plateNode.position
self.sceneView?.scene?.rootNode.addChildNode(lightNode)
lightNode.runAction(
SCNAction.sequence([SCNAction.waitForDuration(0.2 * NSTimeInterval(i)),
SCNAction.repeatActionForever(SCNAction.sequence([
SCNAction.moveTo(SCNVector3(x: lightNode.position.x, y: 2, z: lightNode.position.z), duration: 0.6),
SCNAction.moveTo(SCNVector3(x: lightNode.position.x, y: 0, z: lightNode.position.z), duration: 0)
]))]))
}
}
func createBox() {
let box = SCNBox(width: 0.5, height: 0.5, length: 0.5, chamferRadius: 0)
box.firstMaterial?.diffuse.contents = UIColor.yellowColor()
let boxNode = SCNNode(geometry: box)
boxNode.name = “box”
boxNode.position = SCNVector3(x: –2, y: 0.75, z: –2)
sceneView?.scene?.rootNode.addChildNode(boxNode)
}
func createCamera() {
let camera = SCNNode()
camera.camera = SCNCamera()
camera.position = SCNVector3(x: 0, y: 10, z: 15)
camera.rotation = SCNVector4(x: 1, y: 0, z: 0, w: –0.5)
sceneView?.scene?.rootNode.addChildNode(camera)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
if let touch = touches.first as? UITouch {
let p = touch.locationInView(sceneView)
if let hit = sceneView?.hitTest(p, options: [SCNHitTestSortResultsKey : true])?.first as? SCNHitTestResult {
let box = sceneView?.scene?.rootNode.childNodeWithName(“box”, recursively: false)
let hitpoint = hit.worldCoordinates
let x = box!.position.x
let y = box!.position.y
let z = box!.position.z
let dx : Float = x < hitpoint.x ? 1 : –1
let dz : Float = z < hitpoint.z ? 1 : –1
box?.physicsBody = SCNPhysicsBody.dynamicBody()
box?.physicsBody?.applyForce(SCNVector3(x: dx, y: 2, z: dz), impulse: true)
box?.runAction(SCNAction.sequence([
SCNAction.waitForDuration(0.2),
SCNAction.runBlock { (n : SCNNode!) -> Void in n.physicsBody = nil },
SCNAction.moveTo(SCNVector3(x: x + dx, y: y, z: z + dz), duration: 0.2)
]))
}
}
}
func renderer(aRenderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {
let box = sceneView?.scene?.rootNode.childNodeWithName(“box”, recursively: false)
if sceneView?.scene?.rootNode.hitTestWithSegmentFromPoint(box!.position, toPoint: SCNVector3(x: box!.position.x, y: box!.position.y–3, z: box!.position.z), options: [SCNHitTestSortResultsKey : true])?.first?.node.name == “plate” {
if box?.scale.x < 3.0 {
box?.transform = SCNMatrix4Scale(box!.transform, 1.01, 1.01, 1.01)
}
} else {
if box?.scale.x > 1.0 {
box?.transform = SCNMatrix4Scale(box!.transform, 0.95, 0.95, 0.95)
}
}
}
}
extension Array {
func each(doit:T -> Void) { for i in self { doit(i) }}
}