ランタイム時にARロケーションのVPSカバレッジをクエリする
VPS Coverage APIには、マップに表示したり、 ARLocationManager のローカライゼーションターゲットとして使用するために、ランタイム時にARロケーションを検出する機能が含まれています。
CoverageClientManagerを設定する
 
CoverageClientManager は、Unityエディターでシーンに追加するか、ランタイム時に AddComponent を通じて追加できます。 ARLocationは、ユーザーの現在のGPS位置か、ユーザーが指定した位置(例えば、地図上の都市をリモートで表示する)の周辺にあるARLocationを問い合わせることができます。 また、 CoverageClientManager には、GPS位置の周辺でクエリを実行する半径(メートル単位)を定義するための QueryRadius 設定も含まれています。
Unityプロジェクトでは、ビルドターゲットに対して位置情報へのアクセス許可を設定する必要があります。 iOSでは、 Project Settings(プロジェクト設定) で Location Usage Description(位置情報の使用目的) を設定する必要があります。 Androidの場合、ユーザーはACCESS_FINE_LOCATIONパーミッションを与える必要があり、CoverageClientManagerは使用時にこれを要求します。
以下のコードスニペットは、ユーザーの現在地から 1km 以内にある ARLocation をクエリする CoverageClientManager の設定と構成を示しています。
クリックして、CoverageClientManagerExample.csを表示
using Niantic.Lightship.AR.VpsCoverage;
using UnityEngine;
public class CoverageClientManagerExample : MonoBehaviour
{
    [SerializeField]
    private CoverageClientManager CoverageClientManager;
    public void QueryAroundUser()
    {
        // 指定されていない場合、現在のゲームオブジェクトに追加します。
        if (!CoverageClientManager)
        {
            CoverageClientManager = gameObject.AddComponent<CoverageClientManager>();
        }
        // デバイスの現在位置を使用してカバレッジのクエリを実行します。クエリの半径は1000メートルに設定します。
        CoverageClientManager.UseCurrentLocation = true;
        CoverageClientManager.QueryRadius = 1000;
        
        CoverageClientManager.TryGetCoverage(OnCoverageResult);
    }
    private void OnCoverageResult(AreaTargetsResult result)
    {
        // 現時点では何も処理を行いません。
    }
}
カバレッジ結果を使用する
AreaTargetsResult クラスは、VPS Coverage API クエリからの情報を返します。 Statusが Success であることを確認するか、必要に応じて失敗時の処理を行います。 VPS Coverage APIクエリから返る関連データの大部分は、 AreaTargets リストに含まれます。
エリアターゲットとその内容
各AreaTargetには、CoverageAreaとLocalizationTargetの2つのフィールドが含まれています。
CoverageAreaは、Location ARがサポートされる実世界空間の2次元多角形を定義します。 例えば、 Shape プロパティを使用して、LatLng ポイントを用いたマップ上にオーバーレイを描画し、 LocalizabilityQuality プロパティを使って、そのエリアにおけるトラッキングの全体的な品質を報告します。
LocalizationTargetは、VPSのローカライゼーションがサポートされる実世界空間の点を定義します。 Nameプロパティと ImageURL プロパティは特定の場所に関する情報カードを作成するために使用でき、DefaultAnchor プロパティはトラッキングを開始するために ARLocationManager に渡すことができます。
これらのフィールドとそのプロパティの詳細については、API ドキュメント を参照して下さい。
以下のスニペットは、CoverageArea と LocalizationTarget のデータを組み合わせて、 AreaTargetsResults を使いやすいリストにソートし、フィルタリングする方法を示しています。
クリックして、Area Targetsサンプルスクリプトを表示
using Niantic.Lightship.AR.VpsCoverage;
using UnityEngine;
public class CoverageClientManagerExample : MonoBehaviour
{
    [SerializeField]
    private CoverageClientManager CoverageClientManager;
    public void QueryAroundUser()
    {
        CoverageClientManager.TryGetCoverage(OnCoverageResult);
    }
    private void OnCoverageResult(AreaTargetsResult areaTargetsResult)
    {
        if (areaTargetsResult.Status == ResponseStatus.Success)
        {
            // クエリ位置からの距離でエリアターゲットをソートする
            areaTargetsResult.AreaTargets.Sort((a, b) =>
                a.Area.Centroid.Distance(areaTargetsResult.QueryLocation).CompareTo(
                    b.Area.Centroid.Distance(areaTargetsResult.QueryLocation));
            // 最も近い 5 つの生産品質エリアのみを考慮する
            var maxCount = 5;
            foreach (var result in areaTargetsResult.AreaTargets)
            {
                if (result.Area.LocalizabilityQuality != CoverageArea.Localizability.PRODUCTION)
                {
                    continue;
                }
                
                Debug.Log($"Got a localization target: {result.Target.Name}, anchor payload: {result.Target.DefaultAnchor}");
                maxCount--;
                if (maxCount == 0)
                {
                    break;
                }
            }
        }
        else
        {
            Debug.LogError($"Coverage query failed with status: {areaTargetsResult.Status}");
        }
    }
}
ヒント画像をダウンロードする
それぞれのLocalizationTargetは、ImageURLを含み、これはLocalizationTargetに対応するホストされたヒント画像を指します。 この情報を使用して、ユーザーを現実世界のロケーションに誘導し、ローカライゼーションを行うことができます。 CoverageClientManagerには、ヒント画像をダウンロードしてTextureを作成するユーティリティメソッドがいくつかあります:
クリックしてヒント画像のコードスニペットを表示
using Niantic.Lightship.AR.VpsCoverage;
using UnityEngine;
public class CoverageClientManagerExample : MonoBehaviour
{
    [SerializeField]
    private CoverageClientManager CoverageClientManager;
    public void QueryAroundUser()
    {
        CoverageClientManager.TryGetCoverage(OnCoverageResult);
    }
    private async void OnCoverageResult(AreaTargetsResult areaTargetsResult)
    {
        if (areaTargetsResult.Status == ResponseStatus.Success)
        {
            foreach (var result in areaTargetsResult.AreaTargets)
            {
                if (string.IsNullOrEmpty(result.Target.ImageURL))
                {
                    continue;
                }
                var hintTexture = await CoverageClientManager.TryGetImageFromUrl(result.Target.ImageURL);
                
                // テクスチャを使って何らかの処理を行う
            }
        }
        else
        {
            Debug.LogError($"カバレッジクエリが失敗しました。ステータス: {areaTargetsResult.Status}");
        }
    }
}
ダウンロードとテクスチャ生成のブロックによるパフォーマンスへの影響を考慮し、このAPIは非同期での呼び出しが推奨されています。 また、すべての画像を同時にダウンロードして処理するのではなく、ダウンロードする画像の数を制限することをお勧めします。
CoverageClientManagerの出力をARLocationManagerで使用する
近くの AreaTargets のリストを取得した後、ユーザーやアプリケーションは特定の LocalizationTarget を選択して、 ARLocation としてトラッキングに使用で きます。 以下の例では、レスポンスリストの最初の結果をトラッキングする ARLocation として選択しています。
クリックしてサンプルスクリプトを表示
using Niantic.Lightship.AR.LocationAR;
using Niantic.Lightship.AR.PersistentAnchors;
using Niantic.Lightship.AR.VpsCoverage;
using UnityEngine;
public class CoverageClientManagerExample : MonoBehaviour
{
    [SerializeField]
    private CoverageClientManager CoverageClientManager;
    [SerializeField]
    private ARLocationManager ArLocationManager;
    public void QueryAroundUser()
    {
        CoverageClientManager.TryGetCoverage(OnCoverageResult);
    }
    private void OnCoverageResult(AreaTargetsResult areaTargetsResult)
    {
        if (areaTargetsResult.Status == ResponseStatus.Success)
        {
            var firstResult = areaTargetsResult.AreaTargets[0];
            var anchorPayloadString = firstResult.Target.DefaultAnchor;
            if (string.IsNullOrEmpty(anchorPayloadString))
            {
                // このエリアにアンカーペイロードがない場合は何もしない
                // 実際のアプリケーションでは別のエリアターゲットを選択する
                Debug.LogError($"No anchor found for {firstResult.Target.Name}");
                return;
            }
            var anchorPayload = new ARPersistentAnchorPayload(anchorPayloadString);
            var locationGameObject = new GameObject();
            var arLocation = locationGameObject.AddComponent<ARLocation>();
            arLocation.Payload = anchorPayload;
                
            ArLocationManager.SetARLocations(arLocation);
            ArLocationManager.StartTracking();
        }
        else
        {
            Debug.LogError($"Coverage query failed with status: {areaTargetsResult.Status}");
        }
    }
}
CoverageClientManagerを使用してテストスキャンを表示する
 
CoverageClientManager には、クエリ位置周辺のパブリックVPSロケーションのみが表示されます。 ただし、テストスキャンを手動で CoverageClientManager に追加することで、ロケーションに関係なく、AreaTargetsResult のレスポンスに表示させることができます。 CoverageClientManager PrivateARLocations 配列を使用してテストスキャンの ARLocationManifest を追加すると、実行時にクエリされたかのように AreaTargetsResult 応答に追加されます。 これにより、パブリックVPSロケーションとプライベートなテストスキャンの検出に同じフローを使用することが可能になります。
テストスキャンを作成し、インポートする方法については、テストスキャンを管理するを参照してください。