NetcodeでVPS Colocalizationを使用する

コロカライゼーションは共有ARの重要な要素であり、これによってプレイヤーは現実世界の同じ位置に仮想オブジェクトを表示することができます。 SharedSpaceManager クラスを使用することで、ネットワーク接続を自動的に作成できるだけでなく、VPSが有効な同じロケーションにいるプレイヤーは、別のネットワークインターフェイスを使用せずにマルチプレイヤーARセッションに参加することができます。
前提条件
- ARDKがインストールされたUnityプロジェクトと、セットアップされた基本的なARシーンが必要です。 詳しくは、ARDK のインストールおよび基本的なARシーンの設定を参照してください。
- また、ARシーンにはARLocationも必要です。 ARLocationを追加する方法については、Location ARを使用してコンテンツを現実世界に配置するを参照してください。
 
- この入門ガイドでは、Netcodeを使用して共有ARシーンをセットアップするのプロジェクトをベースとして使用しています。 完了していない場合は、まずこのページの手順を実施してください。
- VPS Colocalizationを使用するには、 SharedSpaceManagerの Colocalization Type が VPS Colocalization に設定されていることを確認してください。
VPS Colocalizationの概要
VPS Colocalizationを設定するには、以下の手順を行う必要があります。
- トラッキングしたいVPSが有効なロケーションを設定します。
- SharedSpaceManager.StartSharedSpace()を呼び出してVPSトラッキングを開始します。
- VPSが「トラッキング中」ステータスになると、共有ARの原点が現実世界のある地点に合わせられます。
- Netcodeを使って共有オブジェクトを表示するの手順に従って、シーン内にオブジェクトをスポーンします。
- Netcodeを起動して、プレイしましょう。
VPSが有効なロケーションをターゲットにする方法には主に2つの方法があります。ランタイム時にCoverage APIを使用してロケーションを選択する方法と、Unityエディター内でVPSが有効なロケーションを設定し、それを中心にアプリケーションをビルドする方法です。 ランタイム時にロケーションを選択するには、ユーザー入力を処理するために必要なUIやコードが増えますが、VPSが有効などのロケーションでも柔軟に対応できるというメリットがあります。 一方、ビルド時にロケーションを設定する方法は前者に比べてシンプルで、特定の空間に基づいて体験を設計できますが、拡張性には欠けるというデメリットがあります。
共有AR体験が、VPSが有効な場所であればどこでもプレイできるように設計されている場合でも、テスト時に特定のロケーションでハードコードすることをお勧めします。 こうすることで、シーンのテストのみを目的とする場合でも、ネットワークUIの問題がさらに発生するのを防ぐことができます。
ARLocationManagerを使用して、VPSが有効なロケーションを設定する
まず、以下の手順で、VPS Colocalization用に SharedSpaceManager を設定します。
- Hierarchy で XR Origin* を選択し、 Inspector で SharedSpaceManagerを見つけます。 Colocalization Type を VPSColocalization に設定します。
- XR Origin を Hierarchy から AR Location Manager コンポーネントにドラッグアンドドロップします。
これで、Shared Space ManagerとAR Location Managerコンポーネントは次のように表示されます。 
テストスキャンを使ってコロカライゼーションをテストする
VPSが有効なロケーションが近くにない場合、テストスキャンを使用して、VPSコロカライゼーションをテストすることができます。 コロカライゼーションのテストスキャンを設定するには、次の手順を行います。
- テストスキャンを管理するの手順に従って、スキャンをAPIキーに追加します。
- メッシュをダウンロードするに進み、指定の手順に従ってメッシュをダウンロードします。
- テストスキャン・マニフェストの緯度と経度を確認してください。 このステップの後まで待つと、問題が発生する可能性があります。
 
- 現実世界のロケーションをUnityに追加するの手順1~3に従って、メッシュをUnityプロジェクトにインストールします。
SharedSpaceManagerでVPS Colocalizationを設定する
VPS Colocalization用にプロジェクトを設定するには、次の手順を行います。
- Hierarchy で、 NetworkDemoManagerの名前をVPSLocationDemoManagerに変更します。
- Project ウィンドウで、 Assets フォルダを開き、 VPSLocationDemoManager.csを開きます。[SerializeField]の呼び出しのリストを見つけ、以下の参照を追加します。
    [SerializeField]
    private ARLocationManager _arLocationManager;
- void Start()のコードを以下のスニペットに置き 換えます。
    // 参加するルームを設定
    // このデモは単一のARLocationを対象としているため、最初のロケーションを使用します
    // リストから選択するアプリケーションの場合、ローカライズする特定のARLocationをルームIDとして使用します。
    var vpsTrackingOptions = ISharedSpaceTrackingOptions.CreateVpsTrackingOptions(_arLocationManager.ARLocations.First());
    var roomOptions = ISharedSpaceRoomOptions.CreateVpsRoomOptions(
        vpsTrackingOptions,
        "optionalPrefixForRoom_", // ルーム名はこのプレフィックスにBase64のロケーションアンカーデータが付加されたものになります
        32, // 収容人数を最大に設定
        "ここにルームの説明を入力します");
    _sharedSpaceManager.StartSharedSpace(vpsTrackingOptions, roomOptions);
この時点で、 VPSLocationDemoManager.cs は次のように表示されます。
クリックして、VPSLocationDemoManagerコードサンプル全体を表示
using System.Linq;
using Niantic.Lightship.AR.Subsystems;
using Niantic.Lightship.SharedAR.Colocalization;
using Unity.Netcode;
using UnityEngine;
public class VPSLocationDemoManager : MonoBehaviour
{
    public SharedSpaceManager SharedSpaceManager;
    public ARLocationManager ARLocationManager;
    public GameObject ConnectionUI;
    private bool _started;
    // Start is called before the first frame update
    void Start()
    {
        SharedSpaceManager.sharedSpaceManagerStateChanged += OnSharedSpaceStateChanged;
        // This demo only targets a single ARLocation, so we can just use the first location.
        // For applications that choose from a list, use the specific ARLocation that you are localizing against
        //  as the room ID
        var vpsTrackingOptions = ISharedSpaceTrackingOptions.CreateVpsTrackingOptions(ARLocationManager.ARLocations.First());
        var roomOptions = ISharedSpaceRoomOptions.CreateLightshipRoomOptions(
        ARLocationManager.ARLocations.First().Payload.ToBase64(),
        10,
        "Room Description Here!"
    );
    _sharedSpaceManager.StartSharedSpace(vpsTrackingOptions, roomOptions);
    }
    private void OnSharedSpaceStateChanged(SharedSpaceManager.SharedSpaceManagerStateChangeEventArgs args)
    {
        if (args.Tracking && !_started)
        {
            ConnectionUI.SetActive(true);
            _started = true;
        }
    }
    public void StartAsHost()
    {
        NetworkManager.Singleton.StartHost();
        ConnectionUI.SetActive(false);
    }
    public void StartAsClient()
    {
        NetworkManager.Singleton.StartClient();
        ConnectionUI.SetActive(false);
    }
}
この時点でアプリケーションをビルドして実行すると、ホストまたはクライアントとして参加するためのボタンと、ローカライゼーションの状態を表示するテキストボックスが表示されます。
 
他のデバイスの位置を表示する
Unity Netcode の NetworkManager を使用して、Owner Authoritative Modeで Player Prefab(プレイヤープレハブ) を設定することで、ピアデバイスの位置を同期し、プレイヤーアバターを正しい位置に表示することができます。
プレイヤープレハブを設定するには、以下の手順を行います。
- 
Hierarchy でARシーンを右クリックし、 Create Empty を選択します。 新しいオブジェクトに playerPrefabという名前を付けます。
- 
playerPrefabを Hierarchy から Project ウィンドウの Assets フォルダにドラッグしてプレハブにし、その後シーンから削除します。
- 
playerPrefabを選択し、 Inspector で Add Component をクリックします。 プレハブにLightshipNetworkObjectコンポーネントを追加し、さらに New Script コンポーネントを追加します。 スクリプトにPlayerAvatarという名前を付けます。
- 
この PlayerAvatarのコードを以下のスクリプトファイルにコピーします。クリックして、PlayerAvatarコードサンプル全体を表示// Copyright 2023 Niantic, Inc. All Rights Reserved.
 using Unity.Netcode.Components;
 using UnityEngine;
 public class PlayerAvatar: NetworkTransform
 {
 [HideInInspector]
 private Transform _arCameraTransform;
 protected override bool OnIsServerAuthoritative()
 {
 return false;
 }
 public override void OnNetworkSpawn()
 {
 if (IsOwner)
 {
 if (Camera.main)
 {
 _arCameraTransform = Camera.main.transform;
 }
 }
 base.OnNetworkSpawn();
 }
 new void Update()
 {
 if (IsOwner)
 {
 if (_arCameraTransform)
 {
 // Get local AR camera transform
 _arCameraTransform.GetPositionAndRotation(out var pos, out var rot);
 // Since using the ClientNetworkTransform, just update world transform of the cube matching with the
 // AR Camera's worldTransform. it's local transform will be synced.
 transform.SetPositionAndRotation(pos, rot);
 }
 }
 base.Update();
 }
 }
このスクリプトでは、サーバーではなく、プレイヤーアバターオブジェクトの所有者によって更新が行われるように、 OnIsServerAuthoritative() から false が返ります。  各プレイヤーオブジェクトは、参加時にNetcodeによって作成され、ユーザーのデバイスによって所有されます。
Position Sync(位置同期)を使ってプレイヤープレハブを最終調整する
プレイヤープレハブを動作させるための最後の要件として、プレイヤーアバターの位置と、そのアバターが表すデバイスの位置が一致していることを確認する必要があります。 PlayerAvatar スクリプトでは、メインカメラのトランスフォーム値がデバイスの位置として使用されます。 プレイヤーアバターとデバイスの位置が正しく一致するように、プレイヤーアバターをメインカメラのトランスフォーム値に合わせて、自動的に位置を同期させます。
位置同期を有効にするには、 Assets フォルダから playerPrefab を選択し、 PlayerAvatar コンポーネントで In Local Space を有効にします。
この時点で、プレイヤープレハブを共有AR体験で使用することができます。 念のため、プレハブの Inspector ビューが次のように表示されていることを確認してください。
 
プレイヤープレハブをテストする
プレイヤープレハブをテストする前に、Network Managerに追加する必要があります。 Hierarchy で NetworkManager を選択し、  playerPrefab を Assets フォルダから Inspector の Player Prefab フィールドにドラッグします。
 
プレハブをNetwork Managerに追加したら、このサンプルを2台のデバイスでビルドして同時に実行します。 セッション内の各デバイスにプレーヤープレファブが表示されるはずです。
 
次のステップ
マルチプレイヤー体験に共有された仮想オブジェクトを追加する方法については、How to Display Shared Objectsをご覧ください。
共有ARの一般的な問題やデバッグの提案については、How to Debug and Troubleshoot Shared ARをご覧ください。