Unity AR入門 平面検出して仮想空間にボールを置いてみた

Unity AR Foundationを使ってARアプリ開発に入門してみました。
2021.11.04

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

UnityでAR開発するにはAR Foundationを使用します。AR FoundationとはiOSやAndroidなどのマルチプラットフォームでARアプリを開発できるようにするためのフレームワークです。iOSにはARKit、AndroidにはARCoreというAR開発ツールがあります。AR Foundationを使えばOSの違いを意識することなくARアプリの実装が可能になります。AR Foundationが対応しているAR機能には平面検出、フェイストラッキング、2D画像検出などがあります。

概要

作成するアプリの内容

今回作成するアプリの大まかな内容です。アプリは1画面で構成され、アプリ起動と同時にカメラが起動します。ユーザーが床を映し、アプリが平面を検出するとそのエリアを可視化します。ユーザーが画面をタップすると、その位置にボールを表示します。

開発環境

  • OS: macOS Monterey
  • Unity Version:2020.3.20f1
  • C#エディター: Visual Studio 2019 for Mac

プラグインのインストールと設定

プラグインのインストール

Unityを起動して3Dでプロジェクトを作成します。エディターが立ち上がったらAR開発で使用するプラグインをインストールします。

  • メニューから [Windows] > [Package Manager]を選択

Package Managerが開いたら、ダイアログ左上[Packages: In Project]から[Packages: Unity Registry]に変更して、以下のプラグインをインストールします。インストールボタンはダイアログの右下に表示されています。ARCoreはAndroid用、ARKitはiOS用のプラグインです。

  • AR Foundation
  • ARCore XR Plugin
  • ARKit XR Plugin

XR Plug-in Managementの設定

XR Plug-in Managementの設定をします。

  • メニューから[Edit] > [Project Settings]
  • iOS: Project Settingsダイアログから [XR Plug-in Management] > iOSタブ > ARKitにチェック
  • Android: Project Settingsダイアログから [XR Plug-in Management] > Androidタブ > ARCoreにチェック

設定が終わったら設定ダイアログを閉じます。

AR SessionとAR Session Originの追加

AR Sessionとは、ARアプリのライフサイクルをコントロールするコンポーネントです。また端末がAR Foundationに対応しているかどうかを調べる際にも使用できます。AR Session Originとは、検出した平面などをUnityシーン内で最終的な位置、向き、スケールに変換するコンポーネントです。子オブジェクトにAR Cameraを持っています。

  • メニューから[GameObject] > [XR] > [AR Session]を選択
  • メニューから[GameObject] > [XR] > [AR Session Origin]を選択

ARを使用するシーンではMainCameraは不要なので削除しておきます。

  • HierarchyでMain Cameraを削除

平面検出を実装する

平面のプレハブを作成する

平面検出時に表示される平面を作成します。

  • [GameObject] > [XR] > [AR Default Plane]を選択
  • 作成したAR Default PlaneをAssetsにドラッグ&ドロップ
  • HierarchyでAD Default Planeを削除

AR Plane Managerの追加

AR Plane Managerを追加することで平面を自動検出することができるようになります。検出した平面を可視化するための設定もします。

  • Hierarchyから[AR Session Origin] > Inspectorから[Add Component] > [AR Plane Manager]を選択
  • AR Plane Managerの Plane Prefab に作成済みのAR Default Planeをドラッグ&ドロップ
  • Detection ModeをHorizontalにする。(Vertricalのチェックを外す)

これで平面検出の準備ができました。

タップした位置にボールを表示する

ボールのプレハブを作成する

画面をタップした時に配置するボールを作成します。

  • [GameObject] > [3D Object] > [Sphere]
  • InspectorのTransformのScaleでX,Y,Zにそれぞれ[0.5]を設定
  • 作成したSphereをAssetsにドラッグ&ドロップ
  • HierarchyにあるSphereを削除

AR Raycast Managerの追加

画面をタップした時に位置を取得するためにAR Raycast Managerを追加します。

  • Hierarchyから[AR Session Origin] > Inspectorから[Add Component] > [AR Raycast Manager]を選択

画面タップ時のスクリプトを作成する

タップした位置にRayを投げ、検出した面にヒットした位置にボールをインスタンス化します。

  • メニューから[Assets] > [Create] > [C# Scripts]
  • 名前をPlaneDetectionに変更
  • 作成したPlaneDetectionのスクリプトをダブルクリックしてエディタ起動
  • 以下のスクリプトを記述して保存
Unity AR Plane Detection

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;

public class PlaneDetection : MonoBehaviour
{
    ARRaycastManager raycastManager;
    [SerializeField] GameObject sphere;

    private void Awake()
    {
        raycastManager = GetComponent<ARRaycastManager>();
    }

    void Update()
    {
        if(Input.touchCount == 0 || Input.GetTouch(0).phase != TouchPhase.Ended || sphere == null)
        {
            return;
        }

        var hits = new List<ARRaycastHit>();
        // TrackableType.PlaneWithinPolygonを指定することによって検出した平面を対象にできる
        if(raycastManager.Raycast(Input.GetTouch(0).position, hits, TrackableType.PlaneWithinPolygon))
        {
            var hitPose = hits[0].pose;
            // インスタンス化
            Instantiate(sphere, hitPose.position, hitPose.rotation);
        }
    }
}
  • Hierarchyから[AR Session Origin] > Inspectorから[Add Component] > [Plane Detection]を選択
  • 作成済みのSphereプレハブをSphereにドラッグ&ドロップ

ビルドする

シーンを追加する

  • メニューから[File] > [Build Settings]
  • Add Open Scenesを選択

Scenes In Build内にSampleSceneが追加されているのを確認してください。

  • Build Settigs左下のPlayer Settingsを選択

ビルド設定(iOS)

  • ARKitのチェックを入れる

ビルド設定(Android)

  • Other Settings内 Graphics APIsからVulkanを削除
  • Identification内 minimum API LevelをAndroid 7.0に変更
  • Configuration内 Scripting BackendをIL2CPPに変更
  • Configuration内 Target ArchitecturesのARM64にチェック

ビルドと実機でのアプリ実行

実機でアプリを実行します。プラットフォームごとに手順が異なります。

ビルドと実行(iOS)

  • メニューから[File] > [Build Settings]
  • [Build And Run]を選択
  • 新しいフォルダを作成して、[Choose]を選択
  • ビルド終了後に、XCodeでプロジェクトファイルを開いて実行
  • XCodeでプロジェクトを開くとプロビジョニングのエラーが出るので解決し、実機を指定してアプリを起動

ビルドと実行(Android)

  • メニューから[File] > [Build Settings]
  • [Build And Run]を選択
  • 出力先やファイル名を指定して[Save]を選択
    • ビルドが終わるとアプリが起動します。

まとめ

Unityを使えば簡単な内容であれば短時間でARアプリを開発できることに衝撃を受けました。最近、新型Meta(Oculus) Quest2を購入したのですが、ハンドトラッキングやデスクの検知、バーチャルキーボード、VR会議などデバイスやサービスの進化に驚かされました。Facebookが社名を変えてまでメタバースに取り組んでいるのを実感しております。HMDやスマートグラスの進化と共に日常にARが取り入れられ、より便利な世界がやってくるのだろうなと思っています。(個人的な願望でもある)

リンク