HoloLens2をさわってみた [第4回_AzureSpatialAnchorsを使った空間同期]

はじめに

こんにちは、エンジニアの伊藤(@kazuyaplus)です。
前回はWindowsDevicePortal を使い2台目のホロレンズに、自作アプリをインストールする方法を紹介しました。

第4回ではAzureSpatialAnchorsを使い、2台のホロレンズで同じオブジェクトを同じ場所で共有する方法を紹介していきたいと思います。

第1回から同じプロジェクトを使用しているので、不明な点がある場合は第1回目から確認してみてください。

  • 第1回 : ひとりで使えるHololens2アプリをつくる ~Unity・VisualStudio・MRTKのインストールからビルドまで ~
  • 第2回 : 他の人と使えるHololens2アプリをつくる ~PUN2を使ってオブジェクトを共有~
  • 第3回 : Tips ~Wi-Fiを使ってアプリをインストール~
  • 第4回 : 他の人と同じ空間で使えるHololens2アプリをつくる ~AzureSpatialAnchorsを使った空間同期~

用語集

  • MRTK
    • [Mixed Reality Toolkit]の略で、AR、VRで使えるUIライブラリ
  • PUN2
    • [Photon Unity Networking2]の略で、Unityにオンライン機能を組み込むためのサービス
  • AzureSpatialAnchors
    • 複数のユーザーが同じ物理的な場所にデジタルコンテンツを配置できるようにするためのサービス

検証環境

  • Unity:2020.3.26f1
  • MRTK:2.7.3
  • VisualStudio:2019
  • Device:HoloLens2

手順

シーンの準備

[Hierarchy]で、SharedPlaygroundオブジェクトを展開し、さらにTableAnchorオブジェクトを展開します。

プロジェクトウィンドウで、Assets > MRTK.Tutorials.MultiUserCapabilities > Prefabsフォルダーに移動し、

ButtonsプレハブをTableAnchorにドラッグして、TableAnchorオブジェクトの子としてシーンに追加します。

シーンを操作するためのボタンの構成

次に、AzureSpatialAnchorsを使用するために、ボタンイベントを設定していきます。

[Hierarchy]で、Buttonオブジェクトを展開し、[StartAzureSession]を選択します。

[Inspector]で、Interactableコンポーネントを見つけ、OnClickイベントを次のように設定します。

  • None(Object)フィールドに、TableAnchorオブジェクトを割り当てます。
  • [NoFunction]から、 AnchorModuleScript > StartAzureSessionを選択します。

次に同じ階層内の、[CreateAzureAnchor]を選択します。

同じように、Interactableコンポーネントを見つけ、OnClickイベントを次のように設定します。

  • None(Object)フィールドに、TableAnchorオブジェクトを割り当てます。
  • [NoFunction]から、 AnchorModuleScript > CreateAzureAnchorを選択します。
  • 表示される新しいNone(Object)フィールドに、TableAnchorオブジェクトを割り当てます

次に同じ階層内の、[ShareAzureAnchor]を選択します。

同じように、Interactableコンポーネントを見つけ、OnClickイベントを次のように設定します。

  • None(Object)フィールドに、TableAnchorオブジェクトを割り当てます。
  • [NoFunction]から、 SharingModuleScript > ShareAzureAnchorを選択します。

次に同じ階層内の、[GetAzureAnchor]を選択します。

同じように、Interactableコンポーネントを見つけ、OnClickイベントを次のように設定します。

  • None(Object)フィールドに、TableAnchorオブジェクトを割り当てます。
  • [NoFunction]から、 SharingModuleScript > GetAzureAnchorを選択します。

Azureアカウントを作成する

AzureSpatialAnchorsを使うために、Azureのアカウントをこちらから作成しましょう。

アカウントを作成したら、画像の赤枠で囲った箇所の[Account ID] [Account Domain] [Primary key]をコピーしておきましょう。

シーンをAzureリソースに接続する

[Hierarchy]で、SharedPlaygroundオブジェクトを展開し、TableAnchorオブジェクトを選択します。

[Inspector]で、Spatial Anchor Manager(スクリプト)コンポーネントを見つけます。

事前に作成したAzureSpatialAnchorsアカウントの情報を使用して[Credentials]セクションを設定します。 

  • [Spatial Anchors Account ID]フィールドに、Azure SpatialAnchorsアカウントの[Account ID]を貼り付けます。
  • [Spatial Anchors Account Domain]フィールドに、Azure SpatialAnchorsアカウントの[Account Domain]を貼り付けます。
  • [Spatial Anchors Account Key]フィールドに、 Azure SpatialAnchorsアカウントから[Primary key]を貼り付けます。

[Hierarchy]でTableAnchorオブジェクトを選択し、[Inspector]で[Anchor Module Script]コンポーネントを見つけます。

[Public Sharing Pin]フィールドで、ピンがプロジェクトに固有になるように数桁を変更します。

TableAnchorオブジェクトを選択したまま、[Inspector]で、すべてのスクリプトコンポーネントが有効になっていることを確認します。

一部スクリプトを追加

既に修正されている可能性があるので要確認ですが、この後、紹介する最後の同期手順の7番でGet Azure Anchorボタンを押すと、

DebugWindow で "Local anchor position successfully set to Azure anchor position" と表示され、

デバイス1と同じ位置にオブジェクトが移動するようになっているはずですが、AnchorModuleScript.cs の、

下記の箇所がなぜか抜けているために、正常に動作しなかったので、私の場合は下記部分を追加しました。

AnchorModuleScript.cs

#if WINDOWS_UWP || UNITY_WSA
                // HoloLens: The position will be set based on the unityARUserAnchor that was located.

                // Create a local anchor at the location of the object in question
                gameObject.CreateNativeAnchor();

                // Notify AnchorFeedbackScript
                OnCreateLocalAnchor?.Invoke();

                // On HoloLens, if we do not have a cloudAnchor already, we will have already positioned the
                // object based on the passed in worldPos/worldRot and attached a new world anchor,
                // so we are ready to commit the anchor to the cloud if requested.
                // If we do have a cloudAnchor, we will use it's pointer to setup the world anchor,
                // which will position the object automatically.
                if (currentCloudAnchor != null)  
                {
                    Debug.Log("Local anchor position successfully set to Azure anchor position");

                    //gameObject.GetComponent<UnityEngine.XR.WSA.WorldAnchor>().SetNativeSpatialAnchorPtr(currentCloudAnchor.LocalAnchor);

                    Pose anchorPose = Pose.identity;
                    anchorPose = currentCloudAnchor.GetPose();

                    Debug.Log($"Setting object to anchor pose with position '{anchorPose.position}' and rotation '{anchorPose.rotation}'");
                    transform.position = anchorPose.position;
                    transform.rotation = anchorPose.rotation;

                    //removeAnchor = "Inactive";
                    //Create a native anchor at the location of the object in question
                    gameObject.CreateNativeAnchor();

                    //Notify AnchorFeedbackScript
                    OnCreateLocalAnchor?.Invoke();

                }

WindowsDevicePortal でメッシュをつくる

空間にアンカーを設定する必要があるので、WindowsDevicePortal を開いて設定していきましょう。

WindowsDevicePortalの開き方については、第3回を確認してください。

WindowsDevicePortalを開き、左のメニューから Views > 3D View を開くと下のような画面になっていると思います。

あたりを少し見まわした後、Spatial mapping > Update を押してみましょう、メッシュが生成されると思います。

メッシュが生成されたら、Spatial anchors > Update を押してみましょう、ロケーターが生成されると思います。

同期手順

ここまで出来たら、準備ができましたので、同期してみましょう。

2つのデバイス間でAzure Anchor IDを共有し空間を同じ配置するためには、次の手順のように進めます。

※AzureSpatialAnchorsはUnityでは実行できません。そのため、AzureSpatialAnchorsの機能をテストするには、2つのデバイスにプロジェクトをビルドする必要があります。

  1. デバイス1(ホスト)の場合:アプリを起動します(インスタンス化されたオブジェクトがテーブルに配置されます)
  2. デバイス2(ゲスト)の場合:アプリを起動します(オブジェクトとアバターが表示されますがホストと同じ場所に表示されません)
  3. デバイス1の場合: [Start Azure Session] ボタンを押します。
  4. デバイス1の場合: [Create Azure Anchor ] ボタンを押します。
  5. デバイス1の場合: [Share Azure Anchor] ボタンを押します。
  6. デバイス2の場合: [Start Azure Session] ボタンを押します。
  7. デバイス2の場合: [Get Azure Anchor] ボタンを押します(デバイス1でアンカーが作成された場所にオブジェクトが移動します)

おわりに

これで、2台のHololens2を使い、同じ空間でオブジェクトを共有することができるようになりました。

4週に渡り、Hololens2の基本的なアプリ作成について紹介しました。

基本的にMicrosoftが用意してある、チュートリアル通りではありますが、私自身がつまずいたりした点に関して補足してあります。

このブログが少しでもHololens2ユーザーの助けになればうれしいです。全4回、お疲れさまでした!

参考リンク

docs.microsoft.com

docs.microsoft.com

github.com