メインコンテンツまでスキップ
バージョン: 0.23.2

空間アンカー

はじめに

このサンプルでは、現実世界の特定の箇所を正確に追跡するために空間アンカーを作成および破棄する方法を紹介します。

空間アンカーに関する基本的な情報や、AR FoundationのAR Anchor Managerコンポーネントの機能については、Unityのドキュメントを参照してください。

機能の有効化

この機能を使用するには、以下のOpenXRのプロジェクト設定でSpatial Anchorsにチェックする必要があります。
Project Settings > XR Plug-in Management > OpenXR (Androidタブ) alt text

サンプルのインポート

まだサンプルをインポートしていない場合は、以下の手順でインポートすることができます。

  1. 基本パッケージのインポート
  2. 基本サンプルのインポート

サンプルシーンは以下の場所に存在します。
Assets/Samples/Snapdragon Spaces/0.XX.0/Core Samples/Scenes/Anchor Sample/Anchor Sample.unity

サンプルの仕組み

シーン内では、アンカーに関するUIパネルがカメラから2メートル先に配置されています。

Place anchor on surfaces (平面にアンカーを配置) トグルを有効にすると、現実世界の平面に対するアンカーの位置を特定するために、毎フレーム頭部の中心から前方にレイが飛ばされます。
ヒットが検出されると、配置されるギズモは黄色に変わります。

スマートフォンのタッチパッドをタップするか、視線インタラクタを選択した場合に表示されるUIパネルで視線を操作すると、空のゲームオブジェクトとARAnchorのゲームオブジェクトがインスタンス化されます。

空のゲームオブジェクトには透明なギズモの3Dモデルがあり、AR Sessionによってトラッキングされます。
ARアンカーのギズモは、ARAnchorManageranchorsChangedイベントによって更新され、トラッキング状態を表します。

    public GameObject GizmoTrackedAnchor;
public GameObject GizmoUntrackedAnchor;

private override void Start() {
FindObjectOfType<ARAnchorManager>().anchorsChanged += OnAnchorsChanged;
}

private void OnAnchorsChanged(ARAnchorsChangedEventArgs args) {
foreach (var anchor in args.added) {
...
}

foreach (var anchor in args.updated) {
Destroy(anchor.transform.GetChild(0).gameObject);
var newGizmo = Instantiate(anchor.trackingState == TrackingState.None ? GizmoUntrackedAnchor : GizmoTrackedAnchor);
newGizmo.transform.SetParent(anchor.transform, false);
}

foreach (var anchor in args.removed) {
...
}
}

全てのアンカーの破壊

alt text 全てのアンカーとギズモは、UIのDestroy All Anchorsを選択することで破壊できます。
削除コマンドは、すべて削除された後に「Select」ボタンでアンカーが作成されるのを防ぐために、遅延を伴って発行されます。

空間アンカーストア

WARNING

トラッキング用のマップを精度高く生成し、保存と読み込みの時間を短縮するために、現実世界では必ず周囲を見回してください。

一度に複数のアンカーを保存するとメインスレッドがブロックされるため、コールバックを使用して後続のアンカーを保存する必要があります。

AR Anchor Managerの隣にSpaces Anchor Storeコンポーネントを追加することで、アンカーをローカルに保存し、後のセッションで認識と追跡を行うことができます。

このコンポーネントは、アンカーのロードと保存、保存したアンカーの削除、アンカーのローカルストレージのクリアのためのAPIを提供します。

namespace Qualcomm.Snapdragon.Spaces
{
public class SpacesAnchorStore
{
public void ClearStore();

public void SaveAnchor(ARAnchor anchor, string anchorName, Action<bool> onSavedCallback = null);
public void SaveAnchor(ARAnchor anchor, Action<bool> onSavedCallback = null);
public void SaveAnchorWithResult(ARAnchor anchor, string anchorName, Action<SaveAnchorResult> onSavedCallback = null);
public void SaveAnchorWithResult(ARAnchor anchor, Action<SaveAnchorResult> onSavedCallback = null);

public void DeleteSavedAnchor(string anchorName);

public void LoadSavedAnchor(string anchorName, Action<bool> onLoadedCallback = null);
public void LoadAllSavedAnchors(Action<bool> onLoadedCallback = null);

public string[] GetSavedAnchorNames();
public string GetSavedAnchorNameFromARAnchor(ARAnchor anchor);
}
}

これらのメソッドについて簡単に紹介します。

  • ClearStore

    • アンカーのローカルストレージをクリアします。
  • SaveAnchor

    • AR Anchorオブジェクトを指定された名前または生成されたハッシュで保存します。完了時にコールバックを呼び出すことができます。
  • SaveAnchorWithResult

    • 指定された名前または生成されたハッシュで、AR Anchorオブジェクトを保存します。完了時にコールバックを呼び出すことができます。
    • SaveAnchorResultに指定できる値は以下の通りです。
      • PENDING: アンカーは保存を保留中です。通常は見ることができないので、代わりにARAnchor.pendingを使用してください。
      • SAVED: ローカルストレージに正常に保存されました。
      • FAILURE_RUNTIME_ERROR: ランタイムエラーのため、ローカルストレージに保存されませんでした。
      • FAILURE_STORE_NOT_LOADED: Spaces Anchor Storeの読み込みに失敗したため、ローカルストレージに保存されませんでした。
      • FAILURE_INSUFFICIENT_QUALITY: 環境マップの品質が不十分なため、ローカルストレージに保存されませんでした。
  • DeleteSavedAnchor

    • ローカルストレージから名前を指定して保存されたアンカーを削除します。
  • LoadSavedAnchor

    • ローカルストレージからアンカーをロードし、シーン内でアンカーを見つけようとします。アンカーが見つかった場合、AR Anchorオブジェクトがインスタンス化されます。ロードされたアンカーは、ARAnchorManageranchorsChangedイベントに追加されたものとしてリストされます。保存されたアンカーの名前はGetSavedAnchorNamesで取得できます。完了時にコールバックを呼び出すことができます。
  • LoadAllSavedAnchors

    • すべてのアンカーをストレージからロードし、シーン内で位置を特定しようとします。LoadSavedAnchorと同様に、AR Anchorオブジェクトは認識されるとインスタンス化されます。
  • GetSavedAnchorNames

    • 保存されているすべてのアンカーを名前で返します。
  • GetSavedAnchorNameFromARAnchor

    • 追跡されたAR Anchorオブジェクトが以前保存されたものであれば、このメソッドはその名前を返し、そうでなければ空文字列を返します。このメソッドは、アンカーが保存されているかどうかをチェックするために使用できます。

サンプルでのアンカーの保存、削除、読み込み

Save new anchors to local store(新しいアンカーをローカルに保存)のトグルを有効にすると、新しいアンカーが作成されるたびに、そのアンカーはローカルに保存されます。

つまり、シーンにAR Anchor Managerがある限り、この保存されたアンカーは他の通常のアンカーとして再作成され、トラッキングされます。
通常のアンカーと保存されたアンカーを区別するために、アンカーの中心に立方体のメッシュが生成されます。立方体が赤い場合は、保存されたアンカーがトラッキングされていないことを意味し、白い場合はトラッキングされていることを意味します。

Load All Saved Anchorsをクリックすると、ローカルに保存されているすべてのアンカーが読み込まれ、その位置を特定しようとします。一方、Clear Storeをクリックすると、ローカル・ストアに保存されているすべてのアンカーが削除されます。この操作では、ストアからロードされた既存のアンカーは破棄されません。