ARを使ったアプリでよく見るARCoachingOverlayViewを使ってみる

2022.05.27

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ARを使ったアプリでよく見かける起動した後に表示されるオンボーディングを使いたかったので調べることにしました。

環境

  • Xcode 13.3
  • iPhone 12mini

はじめに

先日、紹介した垂直方向の平面にアート作品を置くアプリにARCoachingOverlayViewを導入して使ってみたいと思います。

【SwiftUI】ARKitとRealityKitを活用し、特大のアート作品を部屋に置いてみた

ARCoachingOverlayViewとは

特定のゴールに向けてユーザーに標準化された作業指示を表示するViewです。特定のゴールとは、今回のような垂直面を検出する必要があるアプリだと、垂直面を検出する為にユーザーに指示を出します。

ARCoachingOverlayViewが表示されると下記のようなViewが表示されます。

ARKitがトラッキングを確立するには、ユーザーはデバイスを実際に動かして、ARKitが遠近感を得ることができるようにする必要があります。

アプリを起動すると、Coaching Overlayは、ARKitがトラッキングを確立するのを手助けする為にユーザーにデバイスを移動するように求めます。特定の目標を設定した場合、Coaching Overlayはそれに応じて画面に表示する指示を調整します。Coaching Overlayが目標が達成されたと判断し、それ以上のコーチングが不要になると、ユーザーのViewから非表示になります。

ARCoachingOverlayViewを実装する

こちらで作成したアプリのARViewContainerARCoachingOverlayViewを実装していきます。

import RealityKit
import ARKit
import SwiftUI

struct ARViewContainer: UIViewRepresentable {

    func makeUIView(context: Context) -> ARView {
        print("makeUI")
        let arView = ARView(frame: .zero, cameraMode: .ar, automaticallyConfigureSession: true)
        arView.addTapGesture()

        // CoachingOverlayViewをインスタンス化
        let coachingOverlayView = ARCoachingOverlayView()
        // ARViewのセッションに対応
        coachingOverlayView.session = arView.session
        // Delegateを設定
        coachingOverlayView.delegate = context.coordinator

        // アプリの追跡要件を指示する為のゴール
        coachingOverlayView.goal = .verticalPlane
        // セッション状態によって自動でアクティベートするか
        coachingOverlayView.activatesAutomatically = true

        // サイズの調整
        coachingOverlayView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

        // ARViewにARCoachingOverlayViewを追加
        arView.addSubview(coachingOverlayView)

        return arView
    }

    func updateUIView(_ uiView: ARView, context: Context) {}

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, ARCoachingOverlayViewDelegate {

        let parent: ARViewContainer

        init(_ parent: ARViewContainer) {
            self.parent = parent
        }

        func coachingOverlayViewWillActivate(_ coachingOverlayView: ARCoachingOverlayView) {
            // CoachingOverlayViewがアクティブになるタイミングで呼ばれる処理
        }

        func coachingOverlayViewDidDeactivate(_ coachingOverlayView: ARCoachingOverlayView) {
            // Coaching Overlayが完全に非アクティブ化されたときに呼ばれる処理
        }

        func coachingOverlayViewDidRequestSessionReset(_ coachingOverlayView: ARCoachingOverlayView) {
            // セッションの再ローカライズ中に、ユーザーがCoachingOverlayViewの[最初からやり直す]ボタンをタップしたときに呼ばれる処理
        }
    }
}

CoachingOverlayViewを追加する

今回の例ではmakeUIView内でARCoachingOverlayViewを追加しています。

// CoachingOverlayViewをインスタンス化
let coachingOverlayView = ARCoachingOverlayView()
// ARViewのセッションに対応
coachingOverlayView.session = arView.session
// Delegateを設定
coachingOverlayView.delegate = context.coordinator

// アプリの追跡要件を指示する為のゴール
coachingOverlayView.goal = .verticalPlane
// セッション状態によって自動でアクティベートするか
coachingOverlayView.activatesAutomatically = true

// サイズの調整
coachingOverlayView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

// ARViewにARCoachingOverlayViewを追加
arView.addSubview(coachingOverlayView)

まずは、ARCoachingOverlayViewのインスタンスを生成し、ARViewのセッションに対応する為にARViewのセッションをcoachingOverlayView.sessionに代入しています。ARCoachingOverlayViewにはDelegateメソッドがある為、後述するCoordinatorcoachingOverlayView.delegate代入しておきます。

アプリの追跡要件を指示する為のゴール

今回は垂直方向の平面.verticalPlaneをゴールとして設定しました。

coachingOverlayView.goal = .verticalPlane

こちらの設定した値によって、ARCoachingOverlayViewが画面に表示するオンボーディング内容が変わってきます。

ARCoachingOverlayView.Goalは列挙型で指定できるオプションは他にもあります。

  • case anyPlane
    • ゴールとして、任意のタイプの平面を要求します。
  • case horizontalPlane
    • ゴールとして、水平面を要求します。
  • case tracking
    • ゴールとして、基本的なワールドトラッキングを要求します。
  • case verticalPlane
    • ゴールとして、垂直面を要求します。
  • case geoTracking
    • ゴールとして、正確な地理的位置を要求します。

実際のARアプリの内容に合うゴールを設定しましょう。

セッション状態によって自動でアクティベートする

Coaching Overlayを自動的にセットするようにcoachingOverlayView.activatesAutomaticallytrueを設定しています。

coachingOverlayView.activatesAutomatically = true

今回は明示的にtrueを設定していますが、デフォルト値はtrueなので、この記述は書かなくても問題ありません。

activatesAutomaticallytrueをセットすることでセッションが初期化された時、またはトラッキング状態が特定のしきい値を超えて低下した際に自動的にARCoachingOverlayViewがアクティブになり表示されます。

ARViewにARCoachingOverlayViewを追加

// サイズの調整
coachingOverlayView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

// ARViewにARCoachingOverlayViewを追加
arView.addSubview(coachingOverlayView)

autoresizingMask.flexibleWidth.flexibleHeightを設定して、ARViewboundsに応じて幅、高さともに柔軟にリサイズされるようにしておきます。

最後にARViewaddSubview(coachingOverlayView)して完成です。

ARCoachingOverlayViewDelegate

Coordinator内で記述しているDelegateについての説明です。

class Coordinator: NSObject, ARCoachingOverlayViewDelegate {

    let parent: ARViewContainer

    init(_ parent: ARViewContainer) {
        self.parent = parent
    }

    func coachingOverlayViewWillActivate(_ coachingOverlayView: ARCoachingOverlayView) {
        // CoachingOverlayViewがアクティブになるタイミングで呼ばれる処理
    }

    func coachingOverlayViewDidDeactivate(_ coachingOverlayView: ARCoachingOverlayView) {
        // Coaching Overlayが完全に非アクティブ化されたときに呼ばれる処理
    }

    func coachingOverlayViewDidRequestSessionReset(_ coachingOverlayView: ARCoachingOverlayView) {
        // セッションの再ローカライズ中に、ユーザーがCoachingOverlayViewの[最初からやり直す]ボタンをタップしたときに呼ばれる処理
    }
}

coachingOverlayViewWillActivate

文字通り、ARCoachingOverlayViewがアクティブになるタイミングで呼ばれるメソッドです。

AppleのサンプルアプリではARアプリの状態を表示したり、コントロールする為のViewを非表示にする処理を行なっておりました。

func coachingOverlayViewWillActivate(_ coachingOverlayView: ARCoachingOverlayView) {
    upperControlsView.isHidden = true
}

coachingOverlayViewDidDeactivate

Coaching Overlayが目標が達成されたと判断するとユーザーのViewから消え、コーチングプロセスが終了するタイミングで呼ばれるメソッドです。

AppleのサンプルアプリではARアプリの状態を表示したり、コントロールする為のViewを表示させて、アプリが操作できることを視覚的に表現しておりました。

func coachingOverlayViewDidDeactivate(_ coachingOverlayView: ARCoachingOverlayView) {
    upperControlsView.isHidden = false
}

coachingOverlayViewDidRequestSessionReset

セッションの再ローカライズ中に、ARCoachingOverlayView上にStart Overボタンが出てきます。そのボタンを押した時に呼ばれるメソッドです。

Start Overは、最初からやり直すの意味で、AppleのサンプルアプリではAR空間上の状態をリセットする処理を行なっておりました。

func coachingOverlayViewDidRequestSessionReset(_ coachingOverlayView: ARCoachingOverlayView) {
    restartExperience()
}

おわりに

ARアプリを作成する際は、トラッキングを促進させる為にもARCoachingOverlayViewを使用した方がよさそうですね。

今回、ARCoachingOverlayViewの動きを確認する為にAppleがサンプルコードで提供しているサンプルプロジェクトを実機に入れて使ってみたのですが、シンプルながら内容も充実しておりとても良かったです。

同じような物を作る時はとても参考になりそうだと感じました。

Appleサンプルアプリのデモ

モバイルアプリ開発のチームメンバー絶賛募集中!

モバイル事業部では事業会社様と一緒に、数年間にわたり長期でモバイルアプリをグロースさせています。

そんなモバイルアプリ開発のチームメンバーを絶賛募集中です!

もちろんモバイルアプリ開発以外のエンジニアも募集中です!

クラスメソッド採用サイト

参考