作ったサービス
目次
1.本記事でできること
2.動作環境
3.システム構成図
4.Unityプロジェクトの作成
5.ARCore Extensionsインストール
6.ARCoreAPIの取得方法
7.特定の位置にオブジェクトを表示させる
8.まとめ
本記事でできること
こんにちは。位置情報から飲食店に空席状況をAR空間に表示させるサービスを作ってます。前編ではUnityとARCore Geospatial APIを使い特定の位置情報のもとにARコンテンツを表示する方法を紹介します。
ARCore Geospatial APIのインストールやAPIの発行について困っている方の参考になればと思います。
動作環境
AR環境
・Unity 2022.3.49f1
・ARFoundation 5.1.5
・Google ARCore XR Plugin
・ARCore Extensions: 1.46.0
実行デバイス
Galaxy S22 SC-51C
サーバー環境
Flask フレームワーク
ngrok ローカルサーバー
システム構成図
Unityプロジェクトの作成
上記の環境のUnityバージョンをダウンロードします。
https://unity.com/ja/releases/editor/archive
Unity HubでAR Moible
テンプレートを使用してプロジェクトを作成します。
プロジェクトを開けたらそのまま実行します。Game ViewでAR空間をシミュレーションすることができます。実行できたらOKです。
AR Mobileテンプレートを使ってない方は最新バージョンのARFoundationとGoogle ARCore XR Pluginの導入を済ませてください。
ARCore Extensionsインストール
ARCore Extensions: 1.46.0を導入するにはWindow
> Package Manager
を開き左上の+ボタンを押しAdd pacake from git URL...
を押します。
以下のGit URLをコピーして貼り付けます。
https://github.com/google-ar/arcore-unity-extensions.git#arf5
XROriginが割り当てられない方
最新のバージョンだとXROrigin
がスクリプトに参照できないため上記のURLでインストールしてください。
XROrigin
を参照できない方はサンプルシーンをAssetsフォルダーから直接削除してインポートし直すと参照できるようになります。
最新バージョンがインストールされてることを確認したらGeospatial Sample
をインポートします。
Assets
からARCore Extensions
のScenesからGeospatialArf5
シーンを開きます。
AR Core ExtensionsにXR Originが入っているか確認してください。入っていれば次はARCore APIの取得に移ります。実行してもまだエラーが出る状態なので実行できないはずです。
ARCore APIの取得方法
必要なもの
クレジットカード、Googleアカウント
ARCore Geospatial APIを機能させるためのAPIをGCP (Google Cloud Platform) で 発行し取得します。登録にはクレジットカード情報が必要ですが無料の範囲でも使うことができます。
無料で使える範囲を超えるリクエスト数はそれに応じて料金が発生します。
※個人の責任でお願いします。
Google Cloudに登録
URLにアクセス
https://console.cloud.google.com/apis/library/arcore
無料で利用開始
>Googleアカウントにログイン
>クレジットカード情報を入力
確認コードをメールで受け取り入力します。Google CloudへようこそというメールがきたらGoogle Cloudを利用できます。
再度上記のURLへアクセスしARCore APIを有効にします。
プロジェクトは適宜作ってください。
ARCore APIの発行
有効にしたら管理画面が表示されるのでAPIとサービスの認証画面
という文字をクリックしてください。
認証情報を作成をクリックしAPIキーを選択します。しばらく待つとAPIキーが作成できるのでAPIキーをコピーしてください。
APIキーの取り扱いには注意してください。
デモをビルド
取得したAPIキーをUnityに渡す
Edit
>Project Settings
>XR Plug-in Management
>ARCore Extensions
から上記のような設定にしてください。※iOSでビルドしたい方はiOSサポートにチェックをいれて同様にAPIキーをいれてください。
APIキーを入れまだProject Settings
閉じずに
Player
からビルドするプラットフォームのActive Input Handling
をBoth
にします。
(AndroidだとBothにすることを求められる。なぜかはわからない。)
BothにしたらUnityが再起動するので待ちます。
ビルドする前にGeospatial ModeをEnableにします。
では実際にシーンをScene In Build
に追加しビルドしてみます。
デモを実行
いろいろな数値がでてきた。一番上から緯度と経度、高度もあります。Accuracyに関してはこの次で重要なものになります。
特定の位置にオブジェクトを表示させる
特定の位置にオブジェクトを表示するために、ARCore Geospatial APIを使う際の簡単な手順について説明します。
1. Geospatial APIと屋外での使用について
まず、ARCore Geospatial APIはGPSやVPS(Visual Positioning System)を利用して正確な位置情報を取得しますが、屋内ではうまく機能しません。そのため、基本的に屋外での使用をおすすめします。
2. ローカライズのチェック
実際にオブジェクトを表示する前に、位置情報がどれだけ正確かを確認する「ローカライズチェック」を行います。このチェックでは「Accuracy(精度)」の値を確認します。Accuracyの値が低いほど、位置情報が正確であることを意味します。
3. スクリプトの概要
スクリプトを作成し、Accuracyの値が一定のしきい値以下になるまで待機します。しきい値を下回った場合、位置情報の精度が十分に確保されたと判断します。
using Google.XR.ARCoreExtensions;
using System;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;
public class LocalizeCheck : MonoBehaviour
{
// しきい値を設定する(方位角の許容誤差)
public double orientationYawAccuracyThreshold = 16;
// しきい値を設定する(水平精度の許容誤差)
public double horizontalAccuracyThreshold = 14;
// ローカライズが完了したときに実行するアクション
public Action OnFinishedLocalization { get; set; }
// ローカライズが失われたときに実行するアクション
public Action OnLostLocalization { get; set; }
[SerializeField] private AREarthManager earthManager;
private bool isLocalizing;
private bool hasLostLocalization = false;
void Update()
{
bool currentlyLocalizing = IsLocalizing();
if (currentlyLocalizing && !hasLostLocalization)
{
hasLostLocalization = true;
OnLostLocalization?.Invoke(); // イベントを呼び出す
}
else if (!currentlyLocalizing && hasLostLocalization)
{
hasLostLocalization = false;
OnFinishedLocalization?.Invoke(); // イベントを呼び出す
}
}
// ローカライズ状態を判定するメソッド
bool IsLocalizing()
{
// ARセッションと位置情報サービスが正常に動作しているか確認
bool isSessionReady = ARSession.state == ARSessionState.SessionTracking &&
Input.location.status == LocationServiceStatus.Running;
// 現在のARトラッキング状態を取得
var earthTrackingState = earthManager.EarthTrackingState;
// 地理的なポーズを取得(トラッキング中の場合のみ)
var pose = earthTrackingState == TrackingState.Tracking ?
earthManager.CameraGeospatialPose : new GeospatialPose();
// ローカリゼーションの状態を判定し、しきい値を超えている場合はローカリゼーションが不安定と判断
return !isSessionReady ||
earthTrackingState != TrackingState.Tracking ||
pose.OrientationYawAccuracy > orientationYawAccuracyThreshold ||
pose.HorizontalAccuracy > horizontalAccuracyThreshold;
}
}
using Google.XR.ARCoreExtensions;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
public class SampleSpawnObject : MonoBehaviour
{
public double TestLatitude; //出現させたい緯度を入力
public double TestLongitud; //出現させたい経度を入力
private LocationInfo currentLocation;
private LocationServiceStatus Status;
[SerializeField] LocalizeCheck localizeCheck;
public GameObject Prefab;//出現させたいプレファブ
public ARAnchorManager anchorManager;
public AREarthManager earthManager;
GameObject instance;
ARGeospatialAnchor anchor;
void Start()
{
localizeCheck.OnFinishedLocalization += SpawnObject;
localizeCheck.OnLostLocalization += DestroyObject;
}
private void SpawnObject()
{
var pose = earthManager.CameraGeospatialPose;
double targetAltitude = pose.Altitude + 1.5;
var anchor = anchorManager.AddAnchor(
TestLatitude,
TestLongitud,
targetAltitude,
Quaternion.identity
);
instance = Instantiate(Prefab, anchor.transform);
}
private void DestroyObject()
{
if (instance != null)
{
Destroy(instance);
instance = null;
}
if (anchor != null)
{
Destroy(anchor);
anchor = null;
}
}
}
オブジェクトを表示させたい場所の緯度と経度をGoogle Mapからとってきてインスペクター上で貼り付けます。先ほどと同様のシーンをBuild&Runで実行。
実行
まとめ
VPSの中でGeospatial APIはかなり使いやすいと思います。スキャンしなくてもいいというのが最大の利点です。後編ではサーバーから飲食店の空席状況を取得して飲食店の位置に表示させたいと思います。
お読み頂き誠に有難うございました。
参考