[Swift] ARKit2でコードを書かずに太陽系を作ってみた


はじめに!

アプリ開発を学習しているtamakouです。
他の言語と違い、Swiftは参考資料の少なさに困ることもあります。(自分だけでしょうか)
今回はARKit2を使い、コードを書かずに太陽系を作りたいと思います。
Xcodeの機能を使えばARてこんなに簡単にできるんやーと思いました。
↓こういったものを作ります。

コード無し太陽系サンプル動画

少し丁寧に書いていきます。長くなるかもやけど始めましょう。
(・・・・正確に言うとファイル名変更の部分で1行だけいじります)

[1] プロジェクトの作成

まずはプロジェクトを立ち上げましょう。

Create a new Xcode Project -> Augmented Reality App -> ファイル名 create.
とりあえず今回のファイル名は[solarSystem]にしました。

[2] 3Dモデル作成の準備

Xcode左端のナビゲーター内にある、[art.scnassets]を開きます。
そしたら[ship.scn]というファイルがあるかと思います。

この戦闘機はテンプレートモデルであり、今ビルドしてやるとARとしてこいつが表示されます。
とりあえずは今回のファイル名に名前を変えてやりましょう。
[ship.scn] -> [solarSystem.scn]

Scene graph内の[ship][solarSystem]に変えました。
ViewController.swift内の、art.scnassets/ship.scnをsolarSystemに書き換えます。

    // Create a new scene
    let scene = SCNScene(named: "art.scnassets/solarSystem.scn")!

    // Set the scene to the view
    sceneView.scene = scene
}

scnの画面に戻ります。画面を空の状態にしたいので戦闘機は消してしまいましょう。
クリックしてdeleteキーを押せば消えます。

次は太陽や惑星達の画像の用意をします。
この辺りは適当に拾ってくるか、うまいこと自分で画像加工してください。
↓こんな感じの展開図が良いです。

それらの画像を[art.scnassets]の中に入れておきます。
次は実装していきます。

[3] 太陽、惑星を作る

まずはライブラリからsphereを選択します。そして適当に置いてやりましょう。

今置いたのは太陽となります。サイズと位置を整えたいのでXcode右端のユーティリティーよりRadiusと箱型のタブ?の中にてpositionの設定をしてやります。
Radiusは[0.2],positionは[0,0,0]にします。
ちなみにRadiusを1に設定すると結構大きいです。

次にユーティリティーのマルの形をしたタブ?(マテリアル)をクリック。
Properties[Shading][Blinn]
[Diffuse]をクリックし、一覧から画像ファイルを選択。一覧には[art.scnassets]内に入れた画像ファイルが出て来るはず。
今回は太陽なので太陽のテクスチャ用画像を選択。

太陽ができました。

やってる事はとても簡単かと思います。
同じ感じで水星〜海王星を作っていきましょう。
位置は後でまとめて調整すれば良いので星の後方に一個ずつ適当に配置で良いかと。
solarSystem.scn]の下にsphereがたくさん誕生するので、ついでに名前も惑星毎の名前に変更していきます。

こんな感じです。

[4] 土星のリングの作成

このままでは土星が寂しいので、リングを作ります。
ライブラリの[Tube]を画面に置いてやります。

そしたらXcode左側での操作に移ります。

[Tube][saturn]の中に入れてやりましょう。
[Tube]を選んで[saturn]に運ぶだけで簡単に親子関係が作れます。
この時、[Tube]positionを0,0,0にします。

次にDimensions[Tube]の形を整えます。
今回は,
inner radius = 0.1
Outer radius = 0.2
Height = 0.01
としました。
土星ぽくなりましたがまだ物足りない。
[Tube]を選択した状態で、optionを押しながらy軸(上方向)に引っ張りあげます。
そうしたら[Tube]がもう1つ出来上がります。

新しくできた方のScaleを変更します。
[1.5, 1, 1.5]とします。
そしたらこいつも[saturn]に入れてやりましょう。
こいつもpositionを0,0,0にします
[Tube]が2つ[saturn]の下に存在すると思うので、名前を変えてやります。
今回は[Out ringとinner ring]とします。

このままではリングのサイズがおかしいので、inner radiusとOuter radiusをうまく調整してください。
そしてマテリアルを選択しringの色を白っぽい色に変えます。
土星は傾きがあるので(他もあるけどリングがないし目立たないので)傾きも調整します。
positionの下にあるEulerのx軸の数値を変えます。今回は[14,0,0]としました。

よく見る土星の完成です!

次は太陽の周りを回るアニメーションに入っていきます。

[5] アニメーション

このままでは一列に並んだ太陽系です。自転と公転を入れましょう。

まずは自転から設定します。
画面の下からactionsを設定できる欄を引っ張り上げます。
ある人はそのままで。

ライブラリで[rotate action]を選択し下の欄に運びます。

追加された部分にカーソルを合わせると回転矢印マークが左に出てきますのでそれをクリック。
♾マークがあるのでそれをクリック。
無限に回ります。コードでいうrepeat foreverですね。

これだけでは回らないので、回転数を調整します。
Xcode右側にてEuler anglesの数値を設定します。
今回は[0, 10, 0]とします。これで太陽は回転するかと思います。

同じ要領で他の惑星にも自転を与えましょう。

ここまでできれば、Xcode左側にて太陽(sun)を[solarSystem]に入れます。
他の惑星たちも入れてやります。

続いてライブラリから[Empty Node]を選択し、Xcode左の[Mercury]の上に置いてやります。
名前を[Mercury Node]とします。
[Mercury Node]を選択し、ライブラリから[rotate action]を選択。

惑星と同じ要領で設定します。Euler angles[0, 30, 0]とします。

[Mercury Node][Mercury]を入れます。

再生ボタンを押し試してみてください。
太陽の周りを水星が回るはずです。

他の惑星も同じく、[Empty Node] -> [惑星名 Node]に名前変更 -> 惑星を[惑星名 Node]に追加 -> [惑星名 Node]に対し、[rotate action]を追加 -> Euler anglesのy軸の値を変更

あとは[solarSystem]position[0, 0, 1.5]にしましょう。
ここまでできればもう太陽系の完成です。

位置や速度の値は個人差はあるかと思いますが、こんな感じになるでしょうか。

上から見た太陽系サンプル動画2

月などの衛星の追加も同じ要領で試してみてください。
文としては長くなりましたが、作業自体はとても簡単なものです。

終わりに

とても長くなりましたが、誰でも出来る風にかけたのではないでしょうか。
後半少し雑になってきてますが。笑
初学者でも簡単にこういったことが出来るのは良い時代になったなーとつくづく思います。
コードを書くのも良いけど、息抜きにこういったARで遊んで見るのも良いかもしれませんね。
ただ3Dデータを作れるだけではなく、コードと組み合わせて色々できます。
自分は太陽にパーティクルを適用し燃える表現をしました。

ViewController.swift

        // 球体を作成
        let sun = SCNSphere(radius: 0.2)
        // 表面を指定
        sun.firstMaterial?.diffuse.contents = UIImage(named: "sun")
        let sunNode = SCNNode(geometry: sun)
        // 表示位置を指定
        sunNode.position = SCNVector3(0, 0, -1.5)

        // パーティクルシステム
        let particle = SCNParticleSystem(named: "sunFire.scnp", inDirectory: "")
        particle?.emitterShape = sun
        let particleShapePosition = particle?.emitterShape?.boundingSphere.center

        let particleNode = SCNNode()
        particleNode.pivot = SCNMatrix4MakeTranslation(particleShapePosition!.z, particleShapePosition!.x, 0.9)
        particleNode.addParticleSystem(particle!)

        scene.rootNode.addChildNode(particleNode)

雑なコードだったらすみません。笑
これからのAR技術の発展が楽しみです。
tamakou