Edited at

SceneKitでカメラや3Dオブジェクトを動かしてみる(Swiftド素人の非エンジニアが2日でSceneKitで3Dやってみた、の続き。)

More than 1 year has passed since last update.

こちら↓記事の続きです。

http://qiita.com/afroscript10/items/587f48d5aa8c7f3eda0d


カメラを前進させる

前回の記事で下記のようにカメラを追加しました。

        // 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: 0)


runAction()で動きをつける

1行付け加えるだけです。

        // create and add a camera to the scene

let cameraNode = SCNNode()
cameraNode.camera = SCNCamera()
// ★この1行↓を追加したよ★
cameraNode.runAction(SCNAction.repeatForever(SCNAction.moveBy(x: 0, y: -5, z: -20, duration: 1)))
scene.rootNode.addChildNode(cameraNode)

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

cameraNoderunAction(「SCNAction.●●●●」って形で何かの動きを指定)って感じで動きを付け加えます。

runAction()のドキュメントはこちら

SCNActionのドキュメントはこちら


連続した動きはSCNAction.repeatForever()

そして、「SCNAction.●●●●」って形で何かの動きを指定のところに、

SCNAction.repeatForever(「SCNAction.●●●●」って形で何かの連続させたい動きを指定)を使うと、連続した動きを実現できます。

(複雑ですが、SCNActionの中にSCNActionが出てきます。)


平行移動はSCNAction.moveBy()

今回はカメラが前に進んで行くような動きをつけたかったので、画面の奥側(z軸のマイナス方向)に進むように

SCNAction.moveBy(x: 0, y: -5, z: -20, duration: 1)を連続した動きの中に入れました。

※手前方向がz軸の+方向、右がx軸の+方向、上方向がy軸の+方向です。

SCNAction.moveBy(x: 0, y: -5, z: -20, duration: 1)は、x,y,z軸それぞれの方向に対して、それぞれ指定した値分だけ移動します。

duration: 1は「1秒かけて動きますよ」ってことなので、ここの値を小さくすると素早く移動、大きくするとゆっくり移動します。

SCNAction.moveByのドキュメントはこちら


回転させたければSCNAction.rotateBy()

ちなみに、他にも下記のように書くと回転させられたりします。(目が回るので注意を)

cameraNode.runAction(SCNAction.repeatForever(SCNAction.rotateBy(x: 0, y: 2, z: 0, duration: 1)))

SCNAction.rotateBy()のドキュメントはこちら


ドーナッツ(トーラス)たちをy軸方向に動かしてみる。

カメラを動かすのと同様です。前回の記事で、下記のようなコードでトーラスを作りました。

for i in 1...10 {

let torusNode = SCNNode()
torusNode.geometry = SCNTorus(ringRadius: 7, pipeRadius: 1)
let random = Float(arc4random() % 10 )
let randomScale = Float(1 + (arc4random() % 10) / 10)
var t = torusNode.transform
t = SCNMatrix4Scale(t, randomScale, 1, randomScale)
t = SCNMatrix4Rotate(t, Float.pi * 0.5, 1, 0, 0)
t = SCNMatrix4Translate(t, 0, random, -20 - 10 * Float(i))
torusNode.transform = t
scene.rootNode.addChildNode(torusNode)
}

これに1行付け加えるだけです。

for i in 1...10 {

let torusNode = SCNNode()
torusNode.geometry = SCNTorus(ringRadius: 7, pipeRadius: 1)
let random = Float(arc4random() % 10 )
let randomScale = Float(1 + (arc4random() % 10) / 10)
var t = torusNode.transform
t = SCNMatrix4Scale(t, randomScale, 1, randomScale)
t = SCNMatrix4Rotate(t, Float.pi * 0.5, 1, 0, 0)
t = SCNMatrix4Translate(t, 0, random, -20 - 10 * Float(i))
torusNode.transform = t
// ★この1行↓を追加したよ★
torusNode.runAction(SCNAction.repeatForever(SCNAction.rotateBy(x: 0, y: 2, z: 0, duration: 1)))
scene.rootNode.addChildNode(torusNode)
}

同様に回転なら下記ですね。

torusNode.runAction(SCNAction.repeatForever(SCNAction.moveBy(x: 0, y: sin(10), z: 0, duration: 1)))


次にやりたいこと


ドーナッツたちが三角関数的に上下に動くようにする

CommingSoon...

(SCNAction.repeatForever()の中にsin関数を入れて時間変動させればいいのかな?そこらへんがやり方がわからず、詰まってるなう。。。)


カメラを動かして進んでドーナッツをくぐってみる

CommingSoon...

そのうちまた続きを書きます。お楽しみに(??)。