Geospatial API を使って位置情報を利用したARを作ろう!

現地時間で2022/5/11に行われたGoogle I/Oにて、「Geospatial API」という、位置情報を利用してARを出現させる新しい機能が発表されました。

https://webar-lab.palanar.com/news/google-i-o/

精度が話題になっていますが、本記事でもUnityで簡単なデモを作成し、その実態に迫ります。
Geospatial APIのドキュメントはこちらにありますが、今回はUnity(ARFoundation)の項からAndroid向けにビルドを行います。

https://developers.google.com/ar/develop/unity-arf/geospatial/developer-guide-android

APIを有効化する

必要環境
Unityバージョン:2019.4.3f1以降
AR Fountaion:4.1.5以降
ARCore XR プラグイン:4.1.5 以降

Google Cloud PlatformでARCoreを使用するために、APIを有効化する必要があります。リンクを開き、「有効化する」をクリックすると新しいプロジェクトが作成されます。

このページは次の工程でも使用しますので、閉じないように注意してください。

ARCore Extensions for AR Foundationを導入する

Unityを起動し、BuildSettingsよりAndoroidに変更します。(ビルドするために必要な設定も同時におこなうと良いでしょう。)
Window>Package ManagerからARCore Extensions for AR Foundationをインストールします。同時に、ARFoundation、ARCoreXRPluginがインストールされるはずですが、無いようであれば、それぞれPackage Managerから追加しましょう。

また、サンプルも「ARCore Ectensions」の項からインポートできます。

APIキーの登録

次に、APIキーを登録します。(推奨は「Keyless」設定で署名鍵を使用するものですが、本記事では簡略化のためAPIキーを使用します。)
Google Cloud Platformへ戻り、APIキーを取得します。

APIとサービス>認証情報から、「認証情報を生成」をクリックし、APIキーを選択します。作成されたAPIキーをコピーし、Unityに戻ります。

Edit>ProjectSettings>XR Plug-in Management>ARCore Extensionsへ移動し、Android Authentication Strategyを「API Key」に。Android API KeyにコピーしたAPIキーを貼り付けます。
最後に、Optional FeaturesのGeospatial APIにチェックを入れて終了です。

プロジェクトの設定

こちらに従い、プロジェクトに必要なオブジェクトの追加や設定を行います。
Assetsフォルダにある、ARCoreExtensionsConfigのGeospatial Modeを「Enabled」に変更しましょう。
これで準備は完了です。
ここまでやることで、ARCore Extensions for AR Foundationにあるサンプルをアプリで起動することができます。
サンプルでは位置情報と、タップした場所にアンカーを置くことができます。

また、任意の場所にオブジェクトを設置する場合、公式ドキュメントでは下記の記述が紹介されています。

if (earthTrackingState == TrackingState.Tracking)
{
  var anchor =
      AnchorManager.AddAnchor(
          latitude,
          longitude,
          altitude,
          quaternion);
  var anchoredAsset = Instantiate(GeospatialAssetPrefab, anchor.transform);
}

そこで、下記のように記述し、UIボタンにメソッドを設定するようにしました。
(Inspectorウインドウからパラメータを設定します。また、atitudeは今回スマホの高さに指定しています。)
緯度経度の値はGoogleMapから取得が可能です。

 public GameObject GeospatialAssetPrefab;
 public ARAnchorManager AnchorManager;
 public AREarthManager EarthManager;
 public double latitude;
 public double longitude;
 public double altitude;
 public Quaternion quaternion;

    public void SetCube()
    {
        var cameraGeospatialPose = EarthManager.CameraGeospatialPose;
        var earthTrackingState = EarthManager.EarthTrackingState;
        altitude = cameraGeospatialPose.Altitude;

        if (earthTrackingState == TrackingState.Tracking)
        {
            var anchor =
                AnchorManager.AddAnchor(
                    latitude,
                    longitude,
                    altitude,
                    quaternion);
            var anchoredAsset = Instantiate(GeospatialAssetPrefab, anchor.transform);
        }
    }

無事に表示させることができました。
室内などのGoogleMapが入り込めない場所だと1,2m程度の誤差がある印象ですが、道路に面した建物などの座標を指定するとかなり正確に表示されました。

これまでの位置情報を使ったARでは現地のスキャン無しでは作成が難しかった、正確な表示をすることができるため、今後のARの活用場面がかなり広がることでしょう。

※サムネイルは下記より抜粋しました。

https://www.youtube.com/watch?v=udoSz_UBUdc