ARKit 3 で追加された ARCoachingOverlayView
iOS 13 から ARKit に ARCoachingOverlayView が実装された。
ARCoachingOverlayView は
AR でのセッション初期化中やリミテッドトラッキング状況で、ユーザーに視覚的な指示を表示する UI を提供する。
これまでは自力で実装していたものだが、iOS 13 では頑張ってつくらなくてもよい。
実装的には ARSCNView や ARView に ARCoachingOverlayView を addChild して delegate と各種設定をするだけ。
一応、UIView 継承し、親の View の最上部で表示されるため、ARSCNView や ARView ではなくても使用できる。
ただ、ARKit 用であり ARSession が必要なため ARKit の機能が必要になる。
お約束だが、現状はまだ Beta 版なので今後機能の追加、変更、削除される可能性があるので、その点は注意してほしい。
ARCoachingOverlayView のコーチング状態
初期表示 (Phase 1 〜 3)
アプリを起動すると、ARKit はトラッキングを確立するため役立つコーチングオーバーレイが表示。
ユーザーへデバイスを移動するような表示が出る。
コーチングのゴール表示
平面を見つけるなどのコーチングのゴールを選択していると、 コーチングオーバーレイはそれに従って指示を変更する。
完了
平面認識など目標が達成され、それ以上コーチングが必要とされていないと判断した場合はコーチングオーバーレイが非表示になる。
再検出
ARKit の中断などで再度ワールドトラッキングの状態を回復させるなど、ARKit でリローカライズする必要がある場合、
コーチングオーバーレイはリローカライズを支援するようなユーザーをガイドするコーチングオーバーレイを表示する。
ARCoachingOverlayView の実装の流れ
以下を設定すると自動的にオーバーレイの UI が表示される。
- ARCoachingOverlayView を初期化し、ARSCNView などから session を設定。
- 平面認識など認識準備や完了で使用するゴールを設定する
- デリゲートを設定する
- 表示するビューへ ARCoachingOverlayView を addSubView する
デリゲートでは、ARCoachingOverlayView のアクティブになる前、非アクティブになった時、セッションがリセットされた時の関数が要されている。
ARCoachingOverlayView の API
ARCoachingOverlayView
クラスとクラスの使用とイニシャライズ
class ARCoachingOverlayView : UIView
goal
検知したい状態をゴールとして設定し、 コーチングオーバーレイがユーザーに指示する表示が決定される。
var goal: ARCoachingOverlayView.Goal { get set }
表示で設定できる ARCoachingOverlayView.Goal は以下のもので、 垂直/水平平面の両方、水平平面、トラッキング、垂直平面。
- anyPlane
- horizontalPlane
- tracking
- verticalPlane
enum Goal : Int
session
コーチングを表示するために使用するセッション。
ARSession が更新された場合、このプロパティが使用されセッションからコーチングビューも表示される。
var session: ARSession? { get set }
sessionProvider でセッションのデータソースをアクセスできるが、多分直接アクセスすることはあまりないと思う。
@IBOutlet weak var sessionProvider: ARSessionProviding? { get set }
delegate
コーチングイベントのコールバックを設定を実装する。
@IBOutlet weak var delegate: ARCoachingOverlayViewDelegate? { get set }
ARCoachingOverlayViewDelegate のプロトコルは以下の3つで、
アクティブになる前、非アクティブになった時、セッションがリセットされた時に設定する。
func coachingOverlayViewWillActivate(ARCoachingOverlayView) func coachingOverlayViewDidDeactivate(ARCoachingOverlayView) func coachingOverlayViewDidRequestSessionReset(ARCoachingOverlayView)
activatesAutomatically
現在のセッション状態に応じて、コーチングビューが自動的にアクティブにするかどうか設定するフラグ。
このフラグ有効になっている場合は、 セッションが初期化されてた時、またはトラッキング条件が特定のしきい値を低下している場合、コーチングオーバーレイがアクティブになり表示される。
デフォルトは true。 false の場合は isActive で調べ、setActive(_:animated:) を使用してマニュアルで非表示にする。
var activatesAutomatically: Bool { get set }
isActive
コーチングが行われているかどうかを示すフラグ。
activatesAutomatically が有効な場合、このフラグは自動で変化する。
var isActive: Bool { get set }
setActive(_:animated:)
コーチングを行う否かを制御する。
func setActive(_ active: Bool, animated: Bool)
サンプルプロジェクトから実装方法を学ぶ
Placing Objects and Handling 3D Interaction のサンプルは以前あったものを ARKit 3 用に若干修正したもの。
ARCoachingOverlayView の実装されているのでこちらを見ながら説明をしてみる。
実装概要
このプロジェクトで ARCoachingOverlayView が使用されているのは、ViewController+CoachingOverlay.swift 。
この Swift ファイルは Storyboard で initail View Controller となる ViewController クラスのエクステンションで、ARCoachingOverlayViewDelegate プロトコルを使用し delegete を読み込んでいる。
ViewController+CoachingOverlay.swift
このファイルで設定されていないもの
- coachingOverlay は ARCoachingOverlayView
- sceneView は ARSCNView
- upperControlsView は sceneView の上に配置されているボタンの UI(仮想オブジェクトを選択するボタン)
- restartExperience は別の swift ファイルで実装されている AR のリセット処理
初期設定
ARKit をインポートし、ARCoachingOverlayViewDelegate を設定する。
import UIKit import ARKit extension ViewController: ARCoachingOverlayViewDelegate { ... }
デリゲート
coachingOverlayViewWillActivate は ARCoachingOverlayView がアクティブになる前に実行される。
ARCoachingOverlayView が sceneView に表示されるため、その上にある UI である upperControlsView を非表示にする。
func coachingOverlayViewWillActivate(_ coachingOverlayView: ARCoachingOverlayView) { upperControlsView.isHidden = true }
coachingOverlayViewDidDeactivate は ARCoachingOverlayView が非アクティブになった時に実行される。
AR が使用できる状況になるため、使用する UI である upperControlsView を表示する。
func coachingOverlayViewDidDeactivate(_ coachingOverlayView: ARCoachingOverlayView) { upperControlsView.isHidden = false }
coachingOverlayViewDidRequestSessionReset はセッションがリセットされた時に実行される。
ここでは restartExperience() が呼ばれ AR の状態がリセットされ、その後 coachingOverlayViewWillActivate が呼ばれる
func coachingOverlayViewDidRequestSessionReset(_ coachingOverlayView: ARCoachingOverlayView) { restartExperience() }
メインで呼ばれる関数
setupCoachingOverlay() は ViewController の viewDidLoad() で呼ばれため、この関数はアプリ実行時に呼ばれる。
coachingOverlay.session で sceneView.session を渡し、
coachingOverlay.delegate で ViewController の self を渡す。
その後各関数を呼ぶ。
(わかりやすくするため、元のコードから Auto Layout のコンストレイントの記述は省略している)
func setupCoachingOverlay() { coachingOverlay.session = sceneView.session coachingOverlay.delegate = self setActivatesAutomatically() setGoal() }
activatesAutomatically で true に設定している。 デフォルトで true なので明示的に設定している理由は不明。
func setActivatesAutomatically() { coachingOverlay.activatesAutomatically = true }
平面認識を行うため goal で .horizontalPlane を指定し、 平面認識を促す UI を表示する様に設定する。
func setGoal() { coachingOverlay.goal = .horizontalPlane }
まとめ
そもそも ARCoachingOverlayView クラス自体の機能があまりないため、デリゲートを含めても書く部分は少ない。
認識やトラッキングを行う場合、この様な UI の実装を必ずする必要があるので、iOS 13 からはこちらを使用してみるのも良いかもしれない。