じゅころぐAR

ARのブログ

Unity MARSを使って特定の場所にARオブジェクトを自動配置する

2020/6/1にUnity MARSがリリースされたので、まずは評価目的で試用してみました。

unity.com

Unity MARS

MARSはUnityでARアプリケーションを作成するための有料の拡張ツールです。
Mixed and Augmented Reality Studioの頭文字を取ってMARSと略すようです。

UnityでのAR開発といえば、マルチプラットフォームに対応したAR Foundationがありますが、MARSはAR Foundationの上位に位置するツールとなっており、内部でAR Foundationを使っています。

AR Foundationとの違いとして、MARSはクリエイターをメインターゲットとして、複雑なコーディングをしなくても実空間とのインタラクションを含むARアプリケーションを作れることをコンセプトにしているようです。

AR Foundation MARS
使用料 無料 有料($50/month)
ターゲット エンジニア/プログラマー クリエイター

実際に使用してみるとARアプリケーションの作り方が大きく異なるため、利用者のスキルや用途によって選択すべきかと思います。

準備

MARSの利用を開始するまでの流れです。

インストール

MARSは無料トライアル期間付きの有料ツールとなっており、Unityアカウントに決済方法を登録した上で、利用登録が必要です。
登録はUnity MARSのサイトにて"Try for free"のボタンから行えます。

無料トライアルの45日間が終了すると$50/month(または$600/year)の有料サブスクリプションに自動で移行します。
試用のつもりで解除を忘れると課金され続けるので注意しましょう。

登録を行うとUnityアカウントに登録しているメールアドレス宛にメールが届き、メールにUnityPackageをダウンロードするためのURLが記載されています。ダウンロードしたUnityPackageをUnityプロジェクトにインポートすれば利用可能となります。

利用条件

MARSのバージョンに対応したUnityバージョンで、互換性のあるバージョンのAR Foundationをインストールする必要があります。

MARS 1.0.1の場合は、

  • Unityバージョン:"2019.3.x"または"2019.2.x"
  • AR Foundationバージョン:"2.1.8"

となります。

バージョンが合っているかどうかは、MARSをインストールした後、"Window > MARS > Build Settings Check"で確認することができます。

f:id:jyuko49:20200606200356p:plain

文字ばかりで見にくいのですが、Caution(警告)が出ているとビルドに失敗するのでメッセージを確認してバージョンを合わせてください。

サンプルのインポート

MARSのインストーラー実行時、サンプルはインポートされないので必要であれば自身で追加する必要があります。
追加は任意ですが、初めてであれば一度動かしてみた方がよいでしょう。

"Window > Package Manger"から"MARS"を探して、"Samples"に記載されている"MARS Sample Templates"をインポートするとプロジェクトにファイルが追加されます。

f:id:jyuko49:20200606201835p:plain

f:id:jyuko49:20200606202325p:plain

用語と基礎知識

公式のドキュメントを読み込めば色々書いてあるのですが、初見だとわかりにくいと思うので、重要と思われるところをざっくり書いていきます。

Proxy

MARSを使う上で避けられない用語がProxy(プロキシ)です。
公式ドキュメントでもMARS conceptsとして一番にProxyについての説明が書かれています。

Proxyは「代理、代行者」のような意味を持つ英単語で、MARSでは現実空間に存在する物体(リアルオブジェクト)の代わりとしてUnity内で認識されるGameObjectと理解しています。

Proxyには後述するConditions、Actions、Forcesを設定することができます。

Conditions、Actions、Forces

例として、現実空間で椅子の上にオブジェクトをARで表示したいとします。

MARSでどう作っていくかというと、まず椅子を認識するために、椅子の代理としてProxyをシーンに追加します。
次に、椅子であることを認識するためのConditions(状態、条件)をProxyに設定します。Conditionsの例としては、水平面かどうか、平面の広さ、床からの高さなどです。
Conditionsが設定できたら、椅子を認識した後のActions(動作)を設定します。多くのケースでは、ARオブジェクトの表示になるかと思います。

これらの設定を行うと、Conditionsの条件を満たす平面でのみActionsが発生するようになり、椅子の上に自動でオブジェクトが表示されます。

上記の例では不要ですが、ProxyにはForcesも設定することができます。これはProxyが配置された後、他のProxyに追従するような力を加えたりする設定として使えます。

アプリの作成

例として挙げた「特定の場所(椅子の上)にARオブジェクト(球)を自動配置するアプリケーション」を実際に作成してみます。

ビューの設定

MARS用のシーンを構成していくにはMARS Panelを表示して作業した方が色々と便利です。

"Window > MARS > MARS Panel"で表示がオンになります。

f:id:jyuko49:20200606215338p:plain

同様に"Window > MARS > Simulation View"でSimulation Viewも表示しておきましょう。
Simulation Viewは、後述するConditionsの設定に便利です。

f:id:jyuko49:20200606215755p:plain

Proxyの作成

では、早速Proxyを作ってみましょう。基本となるGameObjectの"Proxy Object"をクリックします。

f:id:jyuko49:20200606220300p:plain

シーンに色の着いたひし形のアイコンが表示されると思います。これがProxy Objectです。

f:id:jyuko49:20200606220414p:plain

また、Proxy Objectを配置するとシーンに初期配置されているMain Cameraが自動的にMARS Sessionに置き換わります。

f:id:jyuko49:20200607025005p:plain

続いて、Proxy ObjectのInspectorでProxy (Script)を見てみます。
中段くらいにComponentsというブロックがあり、Conditions、Actions、Forcesが表示されているのがわかるかと思います。

f:id:jyuko49:20200606222243p:plain

クリックして切り替えると、Proxyに現在設定されているMARS Component(Conditions、Actions、Forcesの総称)が表示されます。
初期状態ではActionsが2つ設定されており、ConditionsとForcesはなしになっているはずです。

"Show Children On Tracking Action"はProxyの子オブジェクトを表示状態(Active)にするAction"Set Pose Action"はProxyのPositionを実空間の物体に合わせるActionです。
つまり、Proxyを取得したらその場所に子オブジェクトを表示するActionsが設定されている状態です。

ここにConditionsの設定が必要なのですが、設定に進む前にProxy Objectの子オブジェクトとしてSphereを設定しておきます。

f:id:jyuko49:20200606225906p:plain

Conditionsの設定

初期状態ではConditionsがないため、Proxyは認識されず、アプリを実行しても何も起きません。
"Add Condition..."からいくつかのConditionを追加していきます。

まず、Alignmentを追加してみます。"Alignment Condition"は認識する平面の向きを制限するCoinditionです。

f:id:jyuko49:20200606225053p:plain

今回は上を向いた水平面だけを認識したいので、"HorizontalUp"に設定します。壁などの垂直面(Vertical)や天井などの下を向いた水平面(HorizontalDown)は認識しなくなります。

設定が正しくできているかはアプリをビルドして実機で試してもいいのですが、MARSの特徴でもあるSimulation Viewを使ってテストしてみましょう。
Proxy ObjectのInspector からCompare Toolを見つけて、"Compare In Simulation View"をクリックします。

f:id:jyuko49:20200606230840p:plain

実行すると、Simulation Viewに平面が表示されます。緑色になっている範囲がシミュレーション環境上でProxy Objectを配置できる範囲になります。
Conditionで設定した水平面がすべて表示されています。

f:id:jyuko49:20200607011253p:plain

Compare Toolを実行したまま、Simulation Viewで建物の壁をクリックしてみます。オレンジ色で表示された範囲で垂直面が検出できるのですが、"Alignment: Fail"となっています。

f:id:jyuko49:20200607012421p:plain

このとき、Inspectorの"Alignment Condition"を見ると、"Selected data: Vertical"という赤字のメッセージと"Include"、"Optimaize"ボタンが表示されています。

f:id:jyuko49:20200607012604p:plain

メッセージはSimulation Viewで選択している平面のAlignmentが"Vertical"のため、検出対象外となっていることを示しています。

ここで"Include"を実行すると、現在の条件に加えて選択中の平面も対象に含まれるようにConditionが変更されます。このケースでは"HorizontalUp"と"Vertical"を両方含む"Mixed..."になります。

f:id:jyuko49:20200607013729p:plain

この処理はあくまでAlignmentの設定変更になるので、設定を変更すると垂直面をすべて検出するようになります。選択した平面のみを追加する処理ではないことに注意してください。

f:id:jyuko49:20200607014306p:plain

"Include"ではなく"Optimize"を実行すると、現在の条件を無視して選択中の平面が対象となるようにConditionを最適化します。
このケースでは、Alignmentから"HorizontalUp"の条件が削除され、選択した平面に最適化された条件として"Vertical"になります。

f:id:jyuko49:20200607014855p:plain

動作が確認できたら元の"HorizontalUp"に戻して、別のConditionを追加します。

追加したのは"Plane Size""Height Above Floor"です。

f:id:jyuko49:20200607020732p:plain

"Plane Size Condition"は検知する平面の大きさを制限するConditionです。設定することで、指定した範囲内の大きさの平面だけを検出することができます。
"Minimum Size"と"Maximum Size"はチェックを外すことでいずれか一方の条件のみ適用することができます。

"Height Above Floor Condition"は床からの高さで制限を行うConditionです。"Ideal Height"に検出したい平面の理想の高さを設定します。条件に近い平面が優先して検出されるようになります。
"Range From Ideal Height"は理想の高さから許容する誤差の範囲で、"Require In Range"にチェックを入れるとこの範囲内にない高さの平面は除外されます。

これらのConditionもSimularation Viewでチェックしながら調整ができます。

実機テスト

ここまでの設定で、

  • 床からの高さが0.5±0.2m(=0.3〜0.7m)
  • 広さが 0.3〜1.0m x 0.3〜1.0m
  • 上を向いた水平面

のすべてのConditionsに当てはまったら、

  • 検出した平面の位置にProxyを配置
  • Proxyの子オブジェクト(宙に浮いたSphere)を表示

のActionsが行われます。

実際にビルドして実行してみると、意図した通り、椅子の上にSphereを表示することができました。Conditionsに該当しない床や壁にカメラを向けても反応せず、Actionsは行われません。

f:id:jyuko49:20200607023406p:plain

以上が、MARSによるARアプリ作成の基本的な流れになります。

Tips

説明から省略したもので役立ちそうな機能をいくつか紹介します。

Visualizers

MARS PanelにVisualizersという項目があり、"Planes visualizer"や"Point cloud visualizer"などを簡単にシーンに追加できます。

f:id:jyuko49:20200607122424p:plain

表示させておくと実機でのデバッグに便利です。

f:id:jyuko49:20200607024338p:plain

Forces

アプリ作成例では使いませんでしたが、ProxyにForceを追加すると配置したProxy間で力を加えることができます。

一例として、"Align to Camera"を追加します。

f:id:jyuko49:20200607024625p:plain

どのProxyと紐付けるかを指定するTarget Proxyが"MainCameraProxy"、関係性の種類を指定するTarget Relationが"Center In Front Of And Face"となっており、カメラの向いている方向の前方に追従してProxyが移動するようになります。

f:id:jyuko49:20200607024609p:plain

Forceを設定したProxyをTargetにして、別のProxyにForceを加えることもでき、"「カメラに追従するSphere」に追従するCylinder"のようなForceの設定もできます。

オリジナルのAction作成

Actionsに用意されていない独自のActionを発生させたい場合、スクリプトを自作すれば実装できます。

"Show Children On Tracking Action"と似たActionで、Proxyが取得(Acquire)されたタイミングでPrefabからGameObjectを生成するスクリプトを作成してみると以下のようになります。
Proxyから取得したいイベントのハンドラ(例:IMatchAcquireHandler)を継承して、イベントに対応したメソッド(例:OnMatchAcquire())に実行したい処理を記述するだけです。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.MARS;
using Unity.MARS.Query;

public class CreateObject : MonoBehaviour, IMatchAcquireHandler
{
    [SerializeField]
    private GameObject gameObject;

    public void OnMatchAcquire(QueryResult queryResult) {
        Instantiate(gameObject, this.transform);
    }
}

作成したActionは"Add Action..."の"Other"に追加されています。

f:id:jyuko49:20200607031355p:plain

まとめ

MARSでは実空間とのインタラクションをProxyで管理することができ、Conditionsの条件を満たしたときに自動でActionsを実行します。

AR Foundationとはコンセプトが異なり、現実空間上の意図した場所にARオブジェクトを配置していく機能が充実しているため、現実のレイアウトが想定しやすい空間(イベント・展示会場、美術館など)に対してARオブジェクトを配置していくアプリケーションと相性が良い印象を受けます。

用途が特化している分、AR Foundationにはない機能もあり、MARSが用途に合う開発プロジェクトであれば$50/monthのコストに見合うだけの価値はありそうです。
一方で、最新のAR Foundationバージョンに追従していないことから、MARSだと実装できない機能もあり、柔軟性・拡張性を考えてAR Foundationを使った方がいいケースも多く残りそうです。

とはいえ、MARSに実装されている機能も多すぎて試しきれておらず、

  • 緯度経度ベースでProxyを制限するGeo Fence Condition
  • ActionでNav Meshを作成できると思われるMARS Nav Mesh
  • Image TackingとFace Tracking

など、便利そうな機能もまだまだあります。

MARSとAR Foundationではアプリの作り方が大きく異なるため、両方を学習して使い分けるのか、一方だけを使っていくのかも考えどころです。
AR Foundationで開発ができる方は引き続きAR Foundationを学習しておいた方がよいかなと思いますが、コーディングが苦手でこれからARを始める方ならMARSから試してみるという手もありそうです。