Open12

UnityでGeospatial APIの環境構築手順の備忘録

だんごだんご

やること

Geospatial APIでサンプルシーンに頼らずに自分でシーンを生やしてオブジェクトを出す
ライブラリ自体現状すごくややこしいことになってるのと,公式チュートリアルがだいぶ不親切な書き方なので実験しながらわかったことをかいていきます

環境

Unity 2022.3.5f1
AR Foundation 5.0.7
ARCore Extentions 1.39.0
Android(Pixel 6で実機動作確認)

参考文献

  1. AR Foundation スタートガイド
  2. Geospatial APIを有効にする(Android)
  3. 地理空間アンカー
だんごだんご

必要なものの導入

まずパッケージを入れていきます
Package Managerで,

  • AR FoundationはUnity Registryから入れる
  • ARCore ExtentionsはAdd Packge From gitで,https://github.com/google-ar/arcore-unity-extensions.gitを入力して導入
だんごだんご

必要な設定用オブジェクトを用意する

  1. Package Managerで,ARCore ExtentionsのGeospatial Sampleをいれる
    最新版のAR FoundationではAR Session OriginがXR Originというものに置き換わっており,なんと2023年9月現在Geospatial APIはXR Originに対応してくれていない参考)ため,サンプルシーンは使わなくてもそこからAR Session Originのプレハブを取ってくる必要があります.
    (これはもしかしたらAR Foundationのバージョンを下げることでも対応できるかも…?)
  2. Samples/ARCore Extentions/(バージョン)/Geospatial Sample/ScenesのGeospaitialシーンを開く
  3. "ARCore Extentions", "AR Session Origin", "AR Session"(非アクティブになってる3点セット)をコピーして,自分のシーンに持ってくる
  4. 3つともアクティブにする
サンプルシーンを消したい!って場合
  1. プロジェクトの適当なところで,Create > XR > ARCore Extentions Configでコンフィグを作る
  2. 作ったやつをクリックして,InspectorでGeospatialとStreet Geometry(これは一応つけておく)をEnableに
  3. シーンのARCore ExtentionsオブジェクトのARCore ExtentionコンポーネントのARCore Extentiontion Settingに先ほど作ったものをアタッチする
  4. Samplesを消す
だんごだんご

プラットフォームを変える

ビルドターゲットをAndroidに変える (iOSは今回いったん扱いません)

XR設定の有効化

  1. Player Settings > XR Plug-in ManagementからARCoreを有効化
  2. ARCore Extensionsから,
    1. Android Authentication StrategyをAPI Keyに
    2. Optional FeaturesからGeospatialにチェックを入れる
だんごだんご

APIキーの取得と有効化

このステップはもし既存のAPIキー等が指定されていればスキップ可能

  1. Google Cloud Platformで適当にプロジェクトを作る
  2. ARCore APIをプロジェクト内で有効にする
  3. 認証情報ページに移動し,認証情報を作成>APIキーの順に押す
  4. APIキーが生成されるのでコピーする
  5. Unityに戻り,Player Settings > XR Plug-in Management > ARCore ExtensionsのAndroid API Keyにペースト
だんごだんご

Playerの設定をする

Player Settings > Player > (Androidのマーク) > Other Settingsから,

  1. Rendering > Auto Graphics APIのチェックを外す
  2. Rendering > Graphics APIsからVlukanを消す
  3. Identification > Minimum API Levelのプルダウンから24(Nougat)以上を選択
  4. Configuration > Scripting BackendをIL2CPPに変更
  5. Configuration > Target Architectureのarm64にチェックを入れる

ここまででやっと準備完了

だんごだんご

テスト用スクリプトを書く

次のようなコードを作成(Google公式のチュートリアルコードを一部改変)

using System;
using System.Collections;
using Google.XR.ARCoreExtensions;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;

public class TestPositioner : MonoBehaviour {
    // シーン上のARAnchorManager
    [SerializeField] private ARAnchorManager arAnchorManager;
    [SerializeField] private AREarthManager arEarthManager;
    // オブジェクトの配置場所
    [SerializeField] private double lat;
    [SerializeField] private double lon;
    [SerializeField] private double aboveAlt;

    // 配置タスクが走っているか
    private bool _isFinding = false;
    private MeshRenderer _meshRenderer;

    private void Start() {
        _meshRenderer = GetComponent<MeshRenderer>();
        _meshRenderer.enabled = false;
    }

    void Update() {
        if (!_isFinding && arEarthManager.EarthTrackingState == TrackingState.Tracking) {
            // 対象の座標のアンカーを取得
            var terrainPromise =
                arAnchorManager.ResolveAnchorOnTerrainAsync(lat, lon, aboveAlt, transform.rotation);

            // 非同期にアンカー取得を走らせるコルーチン
            StartCoroutine(CheckTerrainPromise(terrainPromise));
        }
    }

    private IEnumerator CheckTerrainPromise(ResolveAnchorOnTerrainPromise promise) {
        _isFinding = true;
        yield return promise;
        
        // 見つかったアンカーの位置に自身を配置する
        var result = promise.Result;
        if (result.TerrainAnchorState == TerrainAnchorState.Success && result.Anchor != null) {
            var targTrans = result.Anchor.gameObject.transform;
            transform.position = targTrans.position;
            transform.rotation = targTrans.rotation;
            transform.SetParent(targTrans);
            
            _meshRenderer.enabled = true;
        }
        
        yield break;
    }
}
だんごだんご

オブジェクトを配置する

  1. 好きなオブジェクトをシーン上に配置
  2. オブジェクトに先ほど作成したTestAnchorスクリプトをアタッチ
  3. arAnchorManagerに「必要な設定用オブジェクトを用意する」で置いたAR Session Originを入れる
  4. lat, lonに近所の緯度・軽度を入れる
    Google Mapでピンを指すか,Google Earth(後述)が便利
  5. aboveAltに地面からどのくらい高い位置にしたいかを入れる
緯度・軽度をGoogle Earthから調べる

Google Earthだとプロジェクトという形でピンが残ってくれるので,継続的なテストにちょっと便利

  1. Google Earthにアクセスして起動
  2. あらかじめ大体置きたい位置にズームしておく
  3. 左側のメニューから「プロジェクト」を選択
  4. 「新しいプロジェクト」を押す
  5. プロジェクトが作成されるので,「アイテムを追加>目印」を押す
  6. 地図上でオブジェクトを置きたい位置をクリックするとピンが配置される
  7. 右上のメニューボタンから「KMLファイルをエクスポート」を押す
  8. KMLファイルが出てくるので,そこにXMLが入っている
だんごだんご

ビルドする

USBデバッグを許可したAndroid実機をつないでBuild and Runを押すと,実機側で自動的にアプリが立ち上がるので,許可設定(自動でダイアログが出るので許可を押すだけ)をした後にピンを刺した位置にカメラを向けるだけ
デバッグにはAndroid Logcat(Package ManagerのUnity Registryにある)を使うとログが見れて便利

だんごだんご

12/18 追記
どうやらARCore Extionsions 14.0以降だとAndroidのビルドがスタックする問題があるみたい
Unity2021にすると治るらしい…

だんごだんご

12/25 追記
治らなかった
色々やったので確証はないが,なんか知らんが(0,0,0)にオブジェクトを置くとダメ,らしい…?
Clean Buildすると治ったりよくわからない…

だんごだんご

2024 4/11 追記
原因がわかった
Unity以外にJDKがあるとARCoreだかARCore Extentionsだかでビルドエラーが発生するらしい
JDKをアンインストールすることでスタックは解決した