【入門】SwiftでARアプリ

# Swiftを使ってARアプリを作ってみた

ARKitを使用し、太陽系を現実空間に表示するアプリを作成してみた。
環境構築も含め、初学者がARアプリを作成するまでに必要な情報を備忘録的に書き残すこととする。

※本記事は動くオブジェクトを表示するまでとしており、最終的な完成物は以下の記事で紹介している。
[【ARKit】ARでVR空間を作成する](https://qiita.com/shunp/items/aed9235781c9e44acfd2)
[アプリのダウンロードはこちら](https://itunes.apple.com/jp/app/ar宇宙旅行/id1306923658?mt=8)

## 準備編

### Xcodeのインストール

iOSアプリを開発するためにはXcodeが必要。
AppStoreからバージョン9.0(2017/10最新版)をインストールする。

### プロジェクトの作成
XCode起動後、「Create a new Xcode project」を選択する。
「Single View App」を選択し、任意の場所に保存する。
プロジェクト名は「SolarSystem」とする。

以上でアプリ作成準備は完了。
iOSアプリを作成する場合は、基本的にXcodeさえ準備すれば良いのでとても簡単に取りかかれる。
※ARアプリの検証ではシミュレータが使えないので、iPhone等の実機を必ず用意する必要がある。

### ARアプリの画面準備
1. 画面左側の「ProjectNavigater」からMain.storyboardファイルを選択する。
<img width="632" alt="スクリーンショット 2017-11-03 16.55.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/206255/b94a6385-b3c1-6636-3c31-b0dcdf21fcda.png">

2. 画面右下の「Show the Object Library」から「ARKit SceneKit View」を選択し、storyboard画面にドラッグ&ドロップする。
<img width="337" alt="スクリーンショット 2017-11-03 16.57.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/206255/093f60fc-3b3d-e4b8-407d-2cd60b2ce406.png">

3. 「ARSCNView」と書かれた青いオブジェクトをstoryboard画面いっぱいに広げる。
<img width="410" alt="スクリーンショット 2017-11-03 16.59.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/206255/7b845d7a-74fe-1a7f-ea2f-2775397a7337.png">
4. 画面右上のアイコン「Show the Assistant editor」をクリックすると、storyboardの隣に「ViewController.swift」が表示される。
<img width="256" alt="スクリーンショット 2017-11-03 17.00.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/206255/e36949dd-25c4-8eed-4db4-cd18b69e3581.png">

5. 「ARSCNView」と書かれた青いオブジェクトをCtrlキーを押しながらViewControllerへドラッグ&ドロップすると、コネクション情報を設定するポップアップが表示される。
<img width="741" alt="スクリーンショット 2017-11-03 17.02.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/206255/9b3fc669-a55f-1031-8dd9-ff2ca467fa9e.png">

6. 名前を「sceneView」として「OK」を選択すると、以下のプロパティが追加される。

```Swift:ViewController.swift
@IBOutlet weak internal var sceneView: ARSCNView!
```
この「sceneView」に作成したNodeを追加していくことで、
現実世界にオブジェクトを重ねることができる。

## 実装編
### 太陽オブジェクトを作ってみる☀️

まずは太陽系の中心となる太陽オブジェクトを作成する。

```Swift:sample1.swift
// 球体を作成
let sun = SCNNode(geometry: SCNSphere(radius: 0.20)) 

// 表示位置を指定
sun.position = SCNVector3(0, 0, -1) 

// 表面を指定(写真を貼るイメージ)
sun.geometry?.firstMaterial?.diffuse.contents = image 

// ARSCNViewに作成物を追加
sceneView.scene.rootNode.addChildNode(sun)
```

次に、太陽オブジェクトを回転（自転）させる。

```Swift:sample2.swift
// 動きはSCNActionで定義
func doRotation(time: TimeInterval) -> SCNAction {
    let rotation = SCNAction.rotateBy(x: 0, y: CGFloat(Double(360) * .pi/180), z: 0, duration: time)
    let foreverRotation = SCNAction.repeatForever(rotation)
    return foreverRotation
}

// sample1.swiftで作成したNode
sun.runAction(doRotation)

```

### 水星オブジェクトを作ってみる🌕

太陽の周りを公転する水星オブジェクトを作成する。
もちろん公転だけでなく自転することも考慮する必要がある。
まずは太陽の周りを公転する軸を作成する。

```Swift:sample3.swift
// 公転軸
let revolutionAxis = SCNNode()

// 公転軸の位置を指定(太陽の中心位置と同じ)
revolutionAxis.position = SCNVector3(0, 0, -1)

// 公転動作（sample2.swiftのdoRotationと同じ）
let revolution = doRevolution(time: rotationSpeed)
revolutionAxis.runAction(revolution)
```

次に水星オブジェクトを作成し、
sample3.swiftで作成した公転軸に水星オブジェクトを重ねてみる。

```Swift:sample4.swift
// 水星オブジェクトを作成
let mercury = SCNNode(geometry: SCNSphere(radius: 0.03)) 

// 水星の位置を定義（太陽からの距離がx:0.3）
mercury.position = SCNVector3(0.3, 0, 0) 

// 表面を指定(写真を貼るイメージ)
mercury.geometry?.firstMaterial?.diffuse.contents = image 

// 公転軸に水星オブジェクトを追加
revolutionAxis.addChildNode(mercury)
```

ここまでで、太陽とその周りを公転する水星オブジェクトが完成した。

## 完成版

以下サンプルソースコード
※上記関連ファイルは「Sun.swift」「Star.swift」「Mercury.swift」「Planet.swift」が該当する。
https://github.com/shunp/solar-system