コードによる位置情報ARの使い方
このHow-toガイドでは、以下の内容について説明します。
ARLocationManager
パブリック API を使ったARLocation
の管理と追跡- 登録されたARLocationsの更新をリスンする
- ARLocationからの相対的なコンテンツの配置
- ARセッション中に追跡されたARLocationを交換する
前提条件
- ARDK がインストールされたUnityプロジェクトと、セットアップされた基本的な AR シーンが必要です。 詳しくは、ARDK 3のセットアップおよびARシーンのセットアップを参照してください。
- APIキーを追加していない場合は、有効なAPIキーが必要です。
- このHow-Toを使用するには、プロジェクトのARシ ーンに
ARLocationManager
が必要です。 プロジェクトにARLocationManager
とARLocation
を追加する方法については、Unity にリアルワールドのロケーションを追加する のステップ 4 を参照してください。 (ARLocationの交換では、複数のARLocation
が必要になります)。
追跡するARLocationの登録
ARLocationManager
にARLocation
を追加するには、ARLocationManager
のSetARLocationsを呼び出して設定します。
これが呼ばれるたびに、以前に設定されたロケーションはすべてクリアされる。 SetARLocations()
は、StartTracking()
を呼び出す前にのみ呼び出すことができる。 トラッキングする ARLocation
を設定したら、ARLocationManager
の StartTracking() をコールしてトラッキングを開始します。
トラッキングを開始するには、ARLocationManager
のStartTracking() を呼び出します。
ARLocation
は同時に5つまで登録できるが、トラッキングに成功した最初の1つだけが更新を報告する。 複数の場所を同時に追跡しようとすると、追跡のためのネットワーク帯域幅の使用量も増加する。 ユーザーがどこにいるかわかっている場合、またはトラッキングの対象としている場所がある場合、トラッキングするARLocation
を1つだけ登録することを推奨します。 トラッキングの対象が明確でない場合は、複数のロケーションを登録すると便利です。
using Niantic.Lightship.AR.LocationAR;
using UnityEngine;
public class ARLocationTracking : MonoBehaviour
{
[SerializeField]
private ARLocationManager ArLocationManager;
[SerializeField]
private ARLocation[] ArLocations;
public void StartTracking()
{
ArLocationManager.SetARLocations(ArLocations);
ArLocationManager.StartTracking();
}.
}
登録されたARLocationの更新をリスニングする
登録された ARLocations
の更新を受信して処理するには、locationTrackingStateChanged を購読します。
イベントの引数には、更新された ARLocation
と、現在のトラッキング状態を報告する Tracking
という bool
が含まれる。 複数のロケーションが登録されている場合、最初にトラッキングされた ARLocation
だけがイベントを発生します。 その他のARLocations
は自動的に追跡リストから削除されます。
クリックすると更新されたARLocationTrackingスクリプトが表示されます。
using Niantic.Lightship.AR.LocationAR;
using UnityEngine;
using Niantic.Lightship.AR.PersistentAnchors; public class ARLocationTrack : MonoBehavour.PersistentAnchors;
public class ARLocationTracking : MonoBehaviour
{
[SerializeField]
private ARLocationManager ArLocationManager;
[SerializeField]
private ARLocation[] ArLocations;
private bool firstTrackingUpdateReceived = false;
public void StartTracking()
{
ArLocationManager.locationTrackingStateChanged += OnLocationTrackingStateChanged;
ArLocationManager.SetARLocations(ArLocations);
ArLocationManager.StartTracking();
}
private void OnLocationTrackingStateChanged(ARLocationTrackedEventArgs args)
{
var trackedLocation = args.ARLocation;
var isTracking = args.Tracking;
if (!firstTrackingUpdateReceived && isTracking){
Debug.Log("First tracking update received");
firstTrackingUpdateReceived = true;
}
trackedLocation.gameObject.SetActive(isTracking);
}.
}
このスニペットでは、ARLocation
GameObject
はトラッキングの状態によって有効、無効になります。 これは ARLocation
仮想コンテンツが正しくトラッキングできなくなり、AR カメラフィードからオフセットされた場合にトラッキングの損失を処理するのに便利です。
ARLocationを基準としたコンテンツの配置
実行時に ARLocation
から相対的に生成される仮想コンテンツは ARLocation
GameObject
の子オブジェクトでなければなりません。 これにより、ARLocation
のトラッキングが更新されると、仮想コンテンツも更新される。 また、グローバルなトランスフォーム(position
, rotation
)ではなく、ローカルなトランスフォーム(localPosition
, localRotation
)を使用することで、仮想コンテンツを ARLocation
に対して相対的に保つことができます。 ARLocation
からの相対的なローカル変換を保存し、将来のセッションで取得することで、仮想コンテンツを同じ場所に配置することができる。
クリックするとARLocationPlacementスクリプトが表示されます。
using Niantic.Lightship.AR.LocationAR;
using UnityEngine;
public class ARLocationPlacement:MonoBehaviour
{
[SerializeField]
private GameObject GameAsset;
// 既にトラッキングしているARLocation
private ARLocation ArLocation;
// ワールド空間で指定されたポーズでオブジェクトをインスタンス化する(つまり、平面に対するヒットテストの結果)
public GameObject SpawnObjectFromHitTest(Vector3 position, Quaternion rotation)
{
var go = Instantiate(GameAsset, position, rotation);
// 以前に設定したポーズを保持するが、アセットをARLocationにチャイルド
go.transform.SetParent(ArLocation.transform, true);
return go;
}
public void UpdateObjectPosition(Vector3 localPosition, Quaternion localRotation, GameObject go)
{
go.transform.localPosition = localPosition;
go.transform.localRotation = localRotation;
}.
}
コンテンツがずれた場合のトラッキングの更新
時間が経つにつれて、ARSessionのドリフトやARトラッキングが失われることで、ARLocation
が現実世界とずれることがあります。 ARLocation
のトラッキングが失われた場合、 ARLocationManager
はトラッキングが回復すると、自動的に ARLocation
との再接続を試みます。 しかし、すべてのトラッキング・ロスが報告され、処理されているわけではありません。 手動で ARLocation
トラッキングを起動するには、ARLocationManager
の TryUpdateTracking() を呼び出します。
クリックすると更新されたARLocationTrackingスクリプトが表示されます。
using Niantic.Lightship.AR.LocationAR;
using UnityEngine;
public class ARLocationTracking : MonoBehaviour
{
[SerializeField]
private ARLocationManager ArLocationManager;
// これはボタンにアタッチするか、タイマーで呼び出すことができます
// ARLocationが以前に追跡されている必要があります
public void UpdateTracking()
{
ArLocationManager.TryUpdateTracking();
}.
}
位置情報トラッキングの停止
ARLocationManager
のStopTracking() を呼び出すこ とで、ARLocation
のトラッキングを停止することができます。 これは、トラッキングされたロケーションに関連するすべての ARPersistentAnchors
を削除し、すべてのロケーションを非アクティブに設定し、各ARLocation
がまだ存在していれば、階層内の元の親に戻す。 トラッキングセッション間の GameObject
のリークを避けるために、StopTracking()
を呼び出す前に、インスタンス化された GameObject
をデスポーンして破棄することを推奨します。
クリックするとStopTrackingのコード・スニペットが表示されます。
using LocationAR;
using UnityEngine;
public class ARLocationTracking : MonoBehaviour
{
[SerializeField]
private ARLocationManager ArLocationManager;
// 実行時に生成されるGameObject
private GameObject[] SpawnnedGameObjects;
public void StopTracking()
{
foreach (var go in SpawnnedGameObjects)
{
Destroy(go);
}.
ArLocationManager.StopTracking();
}.
}
コードを使用してロケーションを切り替える
ARLocationsはトラッキングが停止しているときにのみ交換できる。 これは、ユーザーが新しい場所に移動したときなど、トラッキングされた
ARLocation を更新するために使用できます。 StopTracking()
を呼び出した後、追跡する新しい ARLocation
を設定して StartTracking()
を呼び出します。 もし SetARLocations
が呼ばれなければ、以前の ARLocations
のセットが使われる。
クリックすると、ロケーション・スワッピングのコード・スニペットが表示されます。
using System.Collections;
using Niantic.Lightship.AR.LocationAR;
using UnityEngine;
public class ARLocationTracking :MonoBehaviour
{
[SerializeField]
private ARLocationManager ArLocationManager;
// 既にトラッキング中
[SerializeField]
private ARLocation InitialLocation;
[SerializeField]
private ARLocation SecondLocation;
public void UpdateLocationForTracking()
{
StartCoroutine(UpdateLocationCoroutine());
}
private IEnumerator UpdateLocationCoroutine()
{
ArLocationManager.StopTracking();
ArLocationManager.SetARLocations(SecondLocation);
// ネイティブシステムとトラッキングをクリアするために1フレーム待ちます
yield return null;
ArLocationManager.StartTracking();
}.
}