🌏

ARCore Geospatial APIをUnityで使ってみる

2022/05/13に公開
18

概要

  • ARCore Geospatial APIとはGoogleの発表したVPS(Visual Positioning Service/System)です
  • ARCoreですが、Android/iOS両方で利用することができます
  • 今回はUnityでのサンプルの動かし方を紹介します

https://developers.google.com/ar/develop/geospatial?hl=ja
https://www.youtube.com/watch?v=PM5rl4z9mto

環境

Unity 2021.3.0f1
AR Fundation 4.2.3
ARCore XR Plugin 4.2.3
ARKit XR Plugin 4.2.3
ARCore Extensions 1.31.0

GCPの設定を行う

  • VPSを利用するためにGCP(Google Cloud Platform)の設定が必要です
  1. プロジェクトの作成
  2. サイドバーで [API とサービス]、[ライブラリ] の順に選択
  3. ARCore API を検索して選択し、[有効にする] をクリックします
  • 次に認証情報を作成します。ドキュメントではAPIキー以外の方法が推奨されていますが、簡単のため今回はAPIキーを利用した方法を紹介します。
  1. APIとサービスから認証情報へ進む

  2. 認証情報を作成でAPIキーを選択

  3. APIキーが作成出来たらどこかにメモっておく

これでGCP側の準備は完了です

Unityの準備

  • まずプロジェクトを作成します。空プロジェクトから設定するよりはARテンプレートを使うと、ある程度初期設定をしてくれるので便利です

  • プロジェクトが開けたら、AndroidまたはiOSにChange Platformします

  • 次にPackage ManagerからGoogle ARCore Extensions for AR Foundationをインストールします

  • Package Managerを開いたら左上の+から Add package from git URL...を選択し下記のURLを入力します。AddするとARCore Extensionsがインストールされます

https://github.com/google-ar/arcore-unity-extensions.git
  • ARCore Extensionsを選択するとGeospatialのSampleがインポートできるようになっているので、こちらもインポートしておきます

  • 次にProjectの設定を行います。まずXR Plug-in Managementを開き、AndroidであればARCore iOSであればARKitを有効にします

  • さらにARCore Extensionsの設定を開き Authentication StrategyAPI Keyに変更し、先ほど入手したAPIキーを貼り付けます

  • Optional FeaturesのGeoSpatialにチェックを入れます

  • また、iOSの場合は iOS Support Enabledにチェックを入れてください

  • iOSの場合はGPSを利用する際に表示するメッセージを設定する必要があります。PlayerSettings->Other Settings->Location Usage Descriptionに任意のメッセージを入れます。これが入っていないとビルドエラーになってしまいます。

  • Assets/Samples/ARCore Extensions/1.31.0/Geospatial Sample/Configurations/GeospatialConfigを開きGeospatial ModeがEnabledになっていることを確認します

これで準備完了です、Geospatialシーンをビルドします
(Development Buildにチェックを入れると、アプリ上でGeospatialのステータスが見られるようになります)

実際に使ってみる

アプリを開くと最初はこの画面が表示されるので、Get Startedをタップします

アプリが起動して、しばらくカメラを向けているとLocalizeが成功して Localization completedが表示されます
そうするとSET ANCHORのボタンが現れ、オブジェクトを設置することができるようになります
アプリがすぐ閉じてしまう場合は、下記のトラブルシューティングを参考にしてみてください

精度について

画面上に表示されている数値の意味は下記のとおりです

意味
Latitude・LAT 緯度
Longitude・LNG 経度
Altitude・ALT 高度
Horizontal Accuracy 緯度と経度の推定水平精度[m]
Vertical Accuracy 推定高度精度[m]
Heading 方位
Heading Accuracy 推定方位精度

Heading Accuracyについては下記のドキュメントが詳しいです。Heading Accuracy=10だった場合、Headingの±10度になる可能性が68%だそうです。Heading Accuracyの値が低いほど精度が高いことを示します。
https://developers.google.com/ar/develop/unity-arf/geospatial/developer-guide-android?hl=ja#adjust_for_pose_accuracy

任意の場所にオブジェクトを配置する

あらかじめオブジェクトが起きたい位置が決まっている場合、緯度・経度・高度・回転を与えることで、その場所にオブジェクトを配置することができます

using Google.XR.ARCoreExtensions;

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

https://developers.google.com/ar/develop/unity-arf/geospatial/developer-guide-android?hl=ja#place_a_geospatial_anchor

リリース後のアップデートで高度を自動で取得してくれるようになりました
この場合はResolveAnchorOnTerrainを使用します。
heightには地表からの高さを指定します
地面に置きたい場合はheightに0を指定します。

var anchor = AnchorManager.ResolveAnchorOnTerrain(
	latitude, 
	longitude, 
	height, 
	quaternion);

トラブルシューティング

error CS0234: The type or namespace name 'iOS' does not exist in the namespace 'UnityEditor' (are you missing an assembly reference?)

これはiOSのモジュールがインストールされてない場合に表示されます。UnityHubからiOSのモジュールをインストールするか、該当の個所を#if UNITY_IOSでくくってコンパイルエラーを消します

ビルドしたアプリがすぐ閉じてしまう

今回使用したサンプルは、エラーが起きるとすぐにアプリを閉じる仕様になっています。しかし、しばらく待つことで初期化が成功することもあるので、ReturnWithReason関数の下2行をコメントアウトしてアプリが閉じないようにします

GeospatialController.cs
private void ReturnWithReason(string reason)
{
    if (string.IsNullOrEmpty(reason))
    {
	return;
    }

    SetAnchorButton.gameObject.SetActive(false);
    ClearAllButton.gameObject.SetActive(false);
    InfoPanel.SetActive(false);

    Debug.LogError(reason);
    SnackBarText.text = reason;
    //_isReturning = true;
    //Invoke(nameof(QuitApplication), _errorDisplaySeconds);
}

EarthStateがErrorInternalになる

  • 通信エラーでアプリがGCPにアクセスできないと、このエラーになるようです
  • 私の場合、Wifiから4Gに切り替えたところ、このエラーは発生しなくなりました

SessionStateがNoneになる

XR Plug-in ManagementARCoreまたはARKitが有効になっていないと、Sessionの初期化が走らずSessionStateがNoneになるようです

Discussion

myaonmyaon

分かりやすい解説記事をありがとうございます!

1点気になる所がありまして、こちらの環境では記事の通りにやると下記のようにErrorInternalという風に出てアプリがすぐ落ちてしまいましたが、Geospatial ConfigのGeospatial modeをdisabledにすると直ってサンプルがそれらしく動きました。中身や違い等はまだ把握できてませんが一旦共有です。

devemindevemin

私も GeospatialConfig のところは Disable (デフォルト)だったのを Enable にしたら、アプリ最初の「Get started」 が出ませんで開始できませんでしたが、
Disable のままにしたらアプリが先に進められ、位置取得が出来ました。

私はAndroid でしたので、iOS 版と挙動が異なるのかもしれませんので参考までに。

素晴らしい記事をありがとうございます。

栗山 和樹栗山 和樹

神記事ありがとうございます!

ReturnWithReason関数の下2行をコメントアウトしてアプリが閉じないようにします

私の端末だとコメントアウトしないと一切先へ進めなかったため非常に助かりました!!

USDJPYLONGUSDJPYLONG

私もUnityでAndroidアプリを作成して試したところ、疑問に思った事がありますので共有させて頂きます。
この新API。GoogleBlogに書かれているように「カメラ画像をストリートビューを元にしたモデルに照会してデバイスの位置と向き決定」を"してなくない"ですか?
ストリートビューと変わりがない特徴的な建物が多い場所をあちこち歩きながらテストしたのですが、
(1)アンカーセットした特徴的な建物やその周辺をカメラに映さなくても、その場所に近づけばアンカーのCGがAR表示される
(2)上記(1)で大まかな位置をつかみ新APIできっちり固定AR表示させるのかと思い、アンカーセットした時と同じアングルで特徴的な建物をカメラに映していても、YouTubeデモ動画のようにアンカーしたCGが安定固定AR表示されず、前後左右上下に動いたり消えたりする
と、アプリの挙動が「どうみてもGPSとジャイロ使っているだけ」なんです。
GCPのAPI使用状況をチェックしますと利用はされているのですが、、、。
AndroidStudio向けのサンプルで試した方がよいのでしょうかね??

Takeshi KadaTakeshi Kada

おそらく内部の動作はGPSでおおよその位置を決定してから、VPSで微調整しているのだと思います
カメラを隠したりするとHorizontal Accuracyの値が悪くなり、周りを見渡すと値が良くなるのでその辺でVPSが機能しているかどうかを確認できると思います

Takeshi KadaTakeshi Kada

Android Nativeの方は試していないので、ちょっとわかりません
申し訳ないです

はちはち

情報とても役に立ちました!
ARcoreテンプレート使わずに試したらEarthStateがErrorInternalになる現象起きてしまい記事を参考にテンプレ使ったら解決できました。
差分を潰して行ったところ原因はデフォルトで設定されてたproguard.txtでライブラリ読めないらしきエラーが出ていた事でした。
テンプレ使わない人はここら辺見直すと良さそうです

oobayashioobayashi

上記の手順通りにやったつもりなんですが、パッケージマネージャーでAdd package from git URLで指定のURLを入力して追加ボタンを押してもArcore extensionsがインストールできません。何が原因なのか対処方法がわかりません。ご教授をお願いいたします。

oobayashioobayashi

Arcore extensionsをインストールすることはできましたが、ビルドがうまくできません。Androidではできないのでしょうか?

Takeshi KadaTakeshi Kada

まず空プロジェクトでAndroidがビルドできるか?から確認するのがいいと思います

oobayashioobayashi

空プロジェクトから、確認していったらスマホにアイコンができるところまでできました。しかし、「EarthStateがErrorInternalになる」になりすぐに落ちてしまいました。とはいえ一通りできたので、ありがとうございます。

まっさんまっさん

こんにちは!

任意の場所にオブジェクトを配置する

この部分について質問なのですが、そのコマンドはどこに書き込めば有効になりますか?

まっさんまっさん


返信ありがとうございます!

つまり、画像ん部分の赤いマーカあたりに構文を書き加えればよい感じでしょうか?

Takeshi KadaTakeshi Kada

場所でいうとそのあたりに該当します
最新のサンプルと記事を書いた時点でのサンプルで差異があるのでご注意ください

やまもとやまもと

geospatial controller.csのコメントアウトをしたのですが、それでもすぐ閉じてしまいます。コメントを削除しても同じ結果になりました。なぜなんでしょうか・・・教えていただきたいです。

Takeshi KadaTakeshi Kada

Invoke(nameof(QuitApplication)
が含まれる行を全てコメントアウトしてみてください
それでも落ちるようでしたら、Geospatial以外の場所で落ちてしまっています
ARテンプレートを使ってAR Foundationが正しく動いているかどうかの確認から始めるといいと思います