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

こちら↓記事の続きです。
http://qiita.com/afroscript10/items/587f48d5aa8c7f3eda0d

#カメラを前進させる

[前回の記事](http://qiita.com/afroscript10/items/587f48d5aa8c7f3eda0d)で下記のようにカメラを追加しました。

```swift
        // 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行付け加えるだけです。

```swift
        // 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()のドキュメントは[こちら](https://developer.apple.com/reference/scenekit/scnactionable/1523164-runaction)
SCNActionのドキュメントは[こちら](https://developer.apple.com/reference/scenekit/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軸それぞれの方向に対して、それぞれ指定した値分だけ移動します。

`ｄｕｒａｔｉｏｎ: 1`は「1秒かけて動きますよ」ってことなので、ここの値を小さくすると素早く移動、大きくするとゆっくり移動します。

SCNAction.moveByのドキュメントは[こちら](https://developer.apple.com/reference/scenekit/scnaction/1523238-moveby)

##回転させたければ`SCNAction.rotateBy（）`

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

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

SCNAction.rotateBy()のドキュメントは[こちら](https://developer.apple.com/reference/scenekit/scnaction/1523522-rotateby)

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

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

```swift
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行付け加えるだけです。

```swift
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)
        }
```

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

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

#次にやりたいこと
##ドーナッツたちが三角関数的に上下に動くようにする
CommingSoon...
(`SCNAction.repeatForever()`の中にsin関数を入れて時間変動させればいいのかな？そこらへんがやり方がわからず、詰まってるなう。。。)
##カメラを動かして進んでドーナッツをくぐってみる
CommingSoon...

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