ARKitのまとめ(実装)
Jul 23, 2017 · iosarkit
概要
WWDC2017で発表されたARKitの実装についてのまとめ
ARKitはARSessionというセッションを通して利用できる
基本的な流れは、セッションを実行しデリゲートで状況の変化を受け取ることになる
Metalを使う場合など自分でレンダリングのループを回したい様な場合は、デリゲートを使わずに一定時間ごとにセッションのオブジェクトにアクセスしてチェックしてもOK
レンダリング用のフレームワークとの連携
ARKitの特徴の一つは、SceneKitやSpriteKitにそれぞれ専用のクラスが準備されていて、オブジェクトのレンダリングまで簡単に連携できる点である
- SceneKit: 3Dの描画用- ARSCNView(- SCNViewのサブクラス)
- ARSCNViewDelegate(- SCNViewDelegate+- ARSessionDelegate)
 
- SpriteKit:- ARSKView(- SKViewのサブクラス)
- ARSKViewDelegate(- SKViewDelegate+- ARSessionDelegate)
 
それぞれのクラスには、あらかじめARSessionがメンバとして存在している。また、カメラでキャプチャされた画像を背景として描画する
使い方
初期設定〜実行
初期設定
カメラのパーミッション
ARKitのアプリを実行するにあたり、カメラのキャプチャを行うので、Info.plistでカメラの利用設定が必須
- Privacy - Camera Usage Description: 利用目的の説明文(初回利用時の許可ダイアログに表示される)
なお、これがないと実行時に落ちる
対応機種の確認
ARKitは実行可能なデバイスが限られている(A9チップ以降)ので、以下のどちらかで対応機種の確認を行う
- インストール自体の制限
 ARKitが必須の場合はInfo.plistで以下の制限を追加し、非対応機種にインストールできなくする- Required device capabilities:- arkit
 
- 実行時の確認
 実行時の確認で良い場合は、以下のフラグで確認する- ARWorldTrackingSessionConfiguration.isSupported
 
実行〜停止
ARSessionの生成
ARSCNViewやARSKViewを使う場合は、特に自分で生成する必要はない。
使わずに自分で生成する場合は、ViewControllerなどのメンバとして保持しておく
設定
何をトラッキングするかといった設定はARSessionConfigurationで指定する
例えば、水平面(床)を検出したい場合は、
let configuration = ARWorldTrackingSessionConfiguration()
configuration.planeDetection = .horizontal
というように設定をする
実行(開始)
セッションを開始するには、一つ前で作成したARSessionConfigurationの設定を引数にしてrunを呼ぶ
// let session = ARSession()
session.run(configuration)
なお、runでオプションの.resetTrackingを指定すると、前回実行時のトラッキング情報をリセットが可能(他にもオプションあり)
停止
セッションはpauseで一時停止できる
session.pause()
再開時は再度、runを呼び出せば良い。ただし、都度ARSessionConfigurationを指定する必要がある
(再開前と同じトラッキングをしたければ、同じ設定を渡す必要がある。
逆に別の設定に切り替えて再開しても良い)
なお、アプリがバックグラウンドにいった場合などは、カメラが利用不可となる為、トラッキングが停止されてしまうので、viewWillDisappearで明示的に停止した方が良いかもしれない(停止時の通知は受信可能)
結果の取得
ARSessionのイベントは、ARSessionDelegateで通知されるので、delegateを登録して受信する
class ViewController: UIViewController, ARSessionDelegate {
    var session: ARSession!
    override func viewDidLoad() {
        ...
        session = ARSession()
        session.delegate = self
    }
    ...
}
なお、ARSCNViewやARSKViewを使う場合はそれぞれ専用のデリゲートが用意されている。
セッション状態のハンドリングは共通であるが、コンテンツのハンドリングはそれぞれ専用になっている
セッション状態のハンドリング
- エラー発生時 - func session(ARSession, didFailWithError: Error)
- セッションが中断した時 
 アプリがバックグラウンドに行ってカメラのキャプチャが中断された場合など- func sessionWasInterrupted(ARSession)
- 中断したセッションが再開された時 - func sessionInterruptionEnded(ARSession)- sessionWasInterruptedの後に呼ばれる
- トラッキング状態(品質)が変わった時 - func session(ARSession, cameraDidChangeTrackingState: ARCamera)
コンテンツのハンドリング
- カメラのキャプチャ画像が更新された時 
 キャプチャ画像と同時にその画像から解析されたAR情報を取得できる- func session(ARSession, didUpdate: ARFrame)- Metalなどで独自レンダリングをする場合に使う想定
- アンカーが追加された時 - func session(ARSession, didAdd: [ARAnchor])
- アンカーが更新された時 - func session(ARSession, didUpdate: [ARAnchor])
- アンカーが削除された時 - func session(ARSession, didRemove: [ARAnchor])
それぞれの具体的な使い方は次回
確認環境
- Xcode9.0 beta3
