SwiftのARKitの基本機能を見てみよう


初めに

今回はSwiftで最近よく使われているARKitの基本機能を実装していきたいと思います。
ARKitまだよくわからない人にとっての入門記事としてはぴったりかなと。
では初めていきます。よろしくお願いします。

導入

まずXcodeを開き、手順は以下です。
Create a new Xcode project

ここでいつものAppではなく、Augmented Reality Appを選択する。

次に、Content Technologyでもうすでに選択されているSceneKitを選択して、自分の指定して位置にアプリを作成する。
そしたら、すでにこのようなサンプルプロジェクトが作られています。

ViewController
import UIKit
import SceneKit
import ARKit

class ViewController: UIViewController, ARSCNViewDelegate {

    @IBOutlet var sceneView: ARSCNView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Set the view's delegate
        sceneView.delegate = self

        // Show statistics such as fps and timing information
        sceneView.showsStatistics = true

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

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

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // Create a session configuration
        let configuration = ARWorldTrackingConfiguration()

        // Run the view's session
        sceneView.session.run(configuration)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        // Pause the view's session
        sceneView.session.pause()
    }

    // MARK: - ARSCNViewDelegate

/*
    // Override to create and configure nodes for anchors added to the view's session.
    func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
        let node = SCNNode()

        return node
    }
*/

    func session(_ session: ARSession, didFailWithError error: Error) {
        // Present an error message to the user

    }

    func sessionWasInterrupted(_ session: ARSession) {
        // Inform the user that the session has been interrupted, for example, by presenting an overlay

    }

    func sessionInterruptionEnded(_ session: ARSession) {
        // Reset tracking and/or remove existing anchors if consistent tracking is required

    }
}

ここでまず初めに不要なものを削除して実機で実行してみることにしましょう。
実機での実行の仕方は、こちらを見てもらえるとわかります。

ViewController
import UIKit
import SceneKit
import ARKit

class ViewController: UIViewController, ARSCNViewDelegate {

    @IBOutlet var sceneView: ARSCNView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Set the view's delegate
        sceneView.delegate = self

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

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

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // Create a session configuration
        let configuration = ARWorldTrackingConfiguration()

        // Run the view's session
        sceneView.session.run(configuration)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        // Pause the view's session
        sceneView.session.pause()
    }
}


ship.scnが浮かび上がっています。

またconfigurationのところをいじることで色々な見え方をデザインすることが出来ます。
一例として、

// Create a session configuration
        //let configuration = ARWorldTrackingConfiguration()
        let configuration = AROrientationTrackingConfiguration()

と置き換えてみてください。

この違いは、ARWorldTrackingConfigurationAROrientationTrackingConfiguration
のドキュメントを見て貰えばわかりやすいのですが、
AROrientationTrackingConfigurationはDeviceの3DのPositionを検知できない構造になっているので、このような違いが出てしまっています。
主に、ARWorldTrackingConfigurationを使うことが多いですが、他にも、色々なconfiguration objectsがあるのでドキュメントを見ながら、実機で試してもらうと面白いですよ。

ここからARKitで使われる基本的な機能の紹介をしていきたいと思います。

Create a 3D Object

次は画面上にcubeを作成していきたいと思います。

ViewController
import UIKit
import SceneKit
import ARKit

class ViewController: UIViewController, ARSCNViewDelegate {

    @IBOutlet var sceneView: ARSCNView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Set the view's delegate
        sceneView.delegate = self

        let cube = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0.01)

        let material = SCNMaterial()

        material.diffuse.contents = UIColor.red

        cube.materials = [material]

        let node = SCNNode()

        node.position = SCNVector3(x: 0, y: 0.1, z: -0.5)

        node.geometry = cube

        sceneView.scene.rootNode.addChildNode(node)

        //いらない部分はコメントアウト
//        // Create a new scene
//        let scene = SCNScene(named: "art.scnassets/ship.scn")!
//
//        // Set the scene to the view
//        sceneView.scene = scene
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        // Create a session configuration
        let configuration = AROrientationTrackingConfiguration()

        // Run the view's session
        sceneView.session.run(configuration)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        // Pause the view's session
        sceneView.session.pause()
    }
}