Jak tworzyć i lokalizować kotwice przy użyciu usługi Azure Spatial Anchors w a unity

Usługa Azure Spatial Anchors umożliwia udostępnianie kotwic na całym świecie między różnymi urządzeniami. Obsługuje kilka różnych środowisk programistycznych. W tym artykule dowiesz się, jak używać zestawu SDK usługi Azure Spatial Anchors w środowisku Unity w celu:

  • Poprawnie skonfiguruj sesję usługi Azure Spatial Anchors i zarządzaj nią.
  • Tworzenie i ustawianie właściwości na lokalnych kotwicach.
  • Przekaż je do chmury.
  • Lokalizowanie i usuwanie kotwic przestrzennych w chmurze.

Wymagania wstępne

Aby ukończyć ten przewodnik, upewnij się, że masz następujące elementy:

  • Zapoznaj się z omówieniem usługi Azure Spatial Anchors.
  • Ukończono jeden z 5-minutowych przewodników Szybki start.
  • Podstawowa wiedza na temat języka C# i aparatu Unity.
  • Podstawowa wiedza na temat arcore , jeśli chcesz używać systemu Android lub ARKit , jeśli chcesz używać systemu iOS.

Cross Platform

Inicjowanie sesji

Głównym punktem wejścia zestawu SDK jest klasa reprezentująca sesję. Zazwyczaj należy zadeklarować pole w klasie, która zarządza widokiem i natywną sesją ar.

Dowiedz się więcej o klasie CloudSpatialAnchorSession .

    CloudSpatialAnchorSession cloudSession;
    // In your view handler
    this.cloudSession = new CloudSpatialAnchorSession();

Konfigurowanie uwierzytelniania

Aby uzyskać dostęp do usługi, musisz podać klucz konta, token dostępu lub token uwierzytelniania entra firmy Microsoft. Więcej informacji na ten temat można również uzyskać na stronie Pojęcia uwierzytelniania.

Klucze kont

Klucze konta to poświadczenia, które umożliwiają aplikacji uwierzytelnianie za pomocą usługi Azure Spatial Anchors. Celem kluczy kont jest ułatwienie szybkiego rozpoczęcia pracy. Szczególnie w fazie opracowywania integracji aplikacji z usługą Azure Spatial Anchors. W związku z tym możesz użyć kluczy konta, osadzając je w aplikacjach klienckich podczas programowania. W miarę postępu poza programowaniem zdecydowanie zaleca się przejście do mechanizmu uwierzytelniania, który jest na poziomie produkcyjnym, obsługiwanym przez tokeny dostępu lub uwierzytelnianie użytkowników firmy Microsoft Entra. Aby uzyskać klucz konta do programowania, odwiedź konto usługi Azure Spatial Anchors i przejdź do karty "Klucze".

Dowiedz się więcej o klasie SessionConfiguration .

    this.cloudSession.Configuration.AccountKey = @"MyAccountKey";

Tokeny dostępu

Tokeny dostępu to bardziej niezawodna metoda uwierzytelniania za pomocą usługi Azure Spatial Anchors. Szczególnie podczas przygotowywania aplikacji do wdrożenia produkcyjnego. Podsumowaniem tego podejścia jest skonfigurowanie usługi zaplecza, za pomocą którego aplikacja kliencka może bezpiecznie się uwierzytelniać. Interfejsy usługi zaplecza z usługą AAD w czasie wykonywania oraz z usługą Bezpiecznego tokenu usługi Azure Spatial Anchors w celu żądania tokenu dostępu. Ten token jest następnie dostarczany do aplikacji klienckiej i używany w zestawie SDK do uwierzytelniania za pomocą usługi Azure Spatial Anchors.

    this.cloudSession.Configuration.AccessToken = @"MyAccessToken";

Jeśli token dostępu nie jest ustawiony, musisz obsłużyć TokenRequired zdarzenie lub zaimplementować tokenRequired metodę w protokole delegata.

Zdarzenie można obsługiwać synchronicznie, ustawiając właściwość na argumentach zdarzeń.

Dowiedz się więcej na temat delegata TokenRequiredDelegate .

    this.cloudSession.TokenRequired += (object sender, TokenRequiredEventArgs args) =>
    {
        args.AccessToken = @"MyAccessToken";
    };

Jeśli musisz wykonać pracę asynchroniczną w procedurze obsługi, możesz odroczyć ustawienie tokenu, żądając deferral obiektu, a następnie wykonując go, tak jak w poniższym przykładzie.

    this.cloudSession.TokenRequired += async (object sender, TokenRequiredEventArgs args) =>
    {
        var deferral = args.GetDeferral();
        string myToken = await MyGetTokenAsync();
        if (myToken != null) args.AccessToken = myToken;
        deferral.Complete();
    };

Uwierzytelnianie Microsoft Entra

Usługa Azure Spatial Anchors umożliwia również aplikacjom uwierzytelnianie za pomocą tokenów microsoft Entra ID (Active Directory). Na przykład możesz użyć tokenów firmy Microsoft Entra do integracji z usługą Azure Spatial Anchors. Jeśli przedsiębiorstwo utrzymuje użytkowników w identyfikatorze Entra firmy Microsoft, możesz podać token firmy Microsoft Entra w zestawie SDK usługi Azure Spatial Anchors. Dzięki temu można uwierzytelniać się bezpośrednio w usłudze Azure Spatial Anchors dla konta należącego do tej samej dzierżawy firmy Microsoft Entra.

    this.cloudSession.Configuration.AuthenticationToken = @"MyAuthenticationToken";

Podobnie jak w przypadku tokenów dostępu, jeśli nie ustawiono tokenu entra firmy Microsoft, musisz obsługiwać zdarzenie TokenRequired lub zaimplementować metodę tokenRequired w protokole delegata.

Zdarzenie można obsługiwać synchronicznie, ustawiając właściwość na argumentach zdarzeń.

    this.cloudSession.TokenRequired += (object sender, TokenRequiredEventArgs args) =>
    {
        args.AuthenticationToken = @"MyAuthenticationToken";
    };

Jeśli musisz wykonać pracę asynchroniczną w procedurze obsługi, możesz odroczyć ustawienie tokenu, żądając deferral obiektu, a następnie wykonując go, tak jak w poniższym przykładzie.

    this.cloudSession.TokenRequired += async (object sender, TokenRequiredEventArgs args) =>
    {
        var deferral = args.GetDeferral();
        string myToken = await MyGetTokenAsync();
        if (myToken != null) args.AuthenticationToken = myToken;
        deferral.Complete();
    };

Konfigurowanie sesji

Wywołaj polecenie Start() , aby umożliwić sesji przetwarzanie danych środowiska.

Aby obsłużyć zdarzenia zgłaszane przez sesję, dołącz procedurę obsługi zdarzeń.

Dowiedz się więcej o metodzie Start .

#if UNITY_ANDROID || UNITY_IOS
    this.cloudSession.Session = aRSession.subsystem.nativePtr.GetPlatformPointer();
#elif UNITY_WSA || WINDOWS_UWP
    // No need to set a native session pointer for HoloLens.
#else
    throw new NotSupportedException("The platform is not supported.");
#endif

    this.cloudSession.Start();

Podawanie ramek do sesji

Sesja zakotwiczenia przestrzennego działa przez mapowanie przestrzeni wokół użytkownika. Dzięki temu można określić, gdzie znajdują się kotwice. Platformy mobilne (iOS i Android) wymagają natywnego wywołania kanału informacyjnego aparatu w celu uzyskania ramek z biblioteki AR platformy. Z kolei urządzenie HoloLens stale skanuje środowisko, więc nie ma potrzeby określonego wywołania, takiego jak na platformach mobilnych.

Dowiedz się więcej o metodzie ProcessFrame .

#if UNITY_ANDROID || UNITY_IOS
    XRCameraFrame xRCameraFrame;
    if (aRCameraManager.subsystem.TryGetLatestFrame(cameraParams, out xRCameraFrame))
    {
        long latestFrameTimeStamp = xRCameraFrame.timestampNs;

        bool newFrameToProcess = latestFrameTimeStamp > lastFrameProcessedTimeStamp;

        if (newFrameToProcess)
        {
            session.ProcessFrame(xRCameraFrame.nativePtr.GetPlatformPointer());
            lastFrameProcessedTimeStamp = latestFrameTimeStamp;
        }
    }
#endif

Przekazywanie opinii użytkownikowi

Możesz napisać kod do obsługi zaktualizowanego zdarzenia sesji. To zdarzenie jest uruchamiane za każdym razem, gdy sesja poprawia zrozumienie otoczenia. Umożliwia to:

  • Użyj klasy , aby przekazać użytkownikowi UserFeedback opinię w miarę przemieszczania się urządzenia, a sesja aktualizuje zrozumienie środowiska. W tym celu
  • Określ, w jakim momencie jest wystarczająco dużo śledzonych danych przestrzennych, aby utworzyć kotwice przestrzenne. Określasz to za pomocą polecenia ReadyForCreateProgress lub RecommendedForCreateProgress. Gdy ReadyForCreateProgress wartość jest wyższa niż 1, mamy wystarczającą ilość danych, aby zapisać kotwicę przestrzenną w chmurze, chociaż zalecamy poczekanie, aż RecommendedForCreateProgress wartość będzie powyżej 1, aby to zrobić.

Dowiedz się więcej na temat delegata SessionUpdatedDelegate .

    this.cloudSession.SessionUpdated += (object sender, SessionUpdatedEventArgs args) =>
    {
        var status = args.Status;
        if (status.UserFeedback == SessionUserFeedback.None) return;
        this.feedback = $"Feedback: {Enum.GetName(typeof(SessionUserFeedback), status.UserFeedback)} -" +
            $" Recommend Create={status.RecommendedForCreateProgress: 0.#%}";
    };

Tworzenie kotwicy przestrzennej chmury

Aby utworzyć kotwicę przestrzenną w chmurze, należy najpierw utworzyć kotwicę w systemie AR platformy, a następnie utworzyć odpowiednik chmury. Należy użyć CreateAnchorAsync() metody .

Dowiedz się więcej o klasie CloudSpatialAnchor .

    // Create a local anchor, perhaps by hit-testing and spawning an object within the scene
    Vector3 hitPosition = new Vector3();
#if UNITY_ANDROID || UNITY_IOS
    Vector2 screenCenter = new Vector2(0.5f, 0.5f);
    List<ARRaycastHit> aRRaycastHits = new List<ARRaycastHit>();
    if(arRaycastManager.Raycast(screenCenter, aRRaycastHits) && aRRaycastHits.Count > 0)
    {
        ARRaycastHit hit = aRRaycastHits[0];
        hitPosition = hit.pose.position;
    }
#elif WINDOWS_UWP || UNITY_WSA
    RaycastHit hit;
    if (this.TryGazeHitTest(out hit))
    {
        hitPosition = hit.point;
    }
#endif

    Quaternion rotation = Quaternion.AngleAxis(0, Vector3.up);
    this.localAnchor = GameObject.Instantiate(/* some prefab */, hitPosition, rotation);
    this.localAnchor.AddComponent<CloudNativeAnchor>();

    // If the user is placing some application content in their environment,
    // you might show content at this anchor for a while, then save when
    // the user confirms placement.
    CloudNativeAnchor cloudNativeAnchor = this.localAnchor.GetComponent<CloudNativeAnchor>();
    if (cloudNativeAnchor.CloudAnchor == null) { await cloudNativeAnchor.NativeToCloud(); }  
    CloudSpatialAnchor cloudAnchor = cloudNativeAnchor.CloudAnchor;
    await this.cloudSession.CreateAnchorAsync(cloudAnchor);
    this.feedback = $"Created a cloud anchor with ID={cloudAnchor.Identifier}");

Jak opisano wcześniej, przed próbą utworzenia nowej zakotwiczenia przestrzennej chmury potrzebne są wystarczające dane środowiska. Oznacza to ReadyForCreateProgress , że musi być powyżej 1, choć zalecamy poczekanie RecommendedForCreateProgress powyżej 1, aby to zrobić.

Dowiedz się więcej o metodzie GetSessionStatusAsync .

    SessionStatus value = await this.cloudSession.GetSessionStatusAsync();
    if (value.RecommendedForCreateProgress < 1.0f) return;
    // Issue the creation request ...

Ustawianie właściwości

Podczas zapisywania kotwic przestrzennych w chmurze możesz dodać pewne właściwości. Podobnie jak typ zapisywanego obiektu lub podstawowe właściwości, takie jak to, czy powinno być włączone na potrzeby interakcji. Może to być przydatne podczas odnajdywania: można natychmiast renderować obiekt dla użytkownika, na przykład ramkę obrazu z pustą zawartością. Następnie inne pobieranie w tle pobiera dodatkowe szczegóły stanu, na przykład obraz do wyświetlenia w ramce.

Dowiedz się więcej o właściwości AppProperties .

    CloudSpatialAnchor cloudAnchor = new CloudSpatialAnchor() { LocalAnchor = localAnchor };
    cloudAnchor.AppProperties[@"model-type"] = @"frame";
    cloudAnchor.AppProperties[@"label"] = @"my latest picture";
    await this.cloudSession.CreateAnchorAsync(cloudAnchor);

Aktualizowanie właściwości

Aby zaktualizować właściwości na kotwicy, należy użyć UpdateAnchorProperties() metody . Jeśli co najmniej dwa urządzenia próbują zaktualizować właściwości dla tej samej kotwicy w tym samym czasie, użyjemy optymistycznego modelu współbieżności. Oznacza to, że pierwszy zapis wygra. Wszystkie inne operacje zapisu otrzymają błąd "Współbieżność": przed ponowną próbą konieczne będzie odświeżenie właściwości.

Dowiedz się więcej o metodzie UpdateAnchorPropertiesAsync .

    CloudSpatialAnchor anchor = /* locate your anchor */;
    anchor.AppProperties[@"last-user-access"] = @"just now";
    await this.cloudSession.UpdateAnchorPropertiesAsync(anchor);

Nie można zaktualizować lokalizacji kotwicy po jej utworzeniu w usłudze — musisz utworzyć nową kotwicę i usunąć ją, aby śledzić nową pozycję.

Jeśli nie musisz lokalizować kotwicy, aby zaktualizować jej właściwości, możesz użyć GetAnchorPropertiesAsync() metody , która zwraca CloudSpatialAnchor obiekt z właściwościami.

Dowiedz się więcej o metodzie GetAnchorPropertiesAsync .

    var anchor = await cloudSession.GetAnchorPropertiesAsync(@"anchorId");
    if (anchor != null)
    {
        anchor.AppProperties[@"last-user-access"] = @"just now";
        await this.cloudSession.UpdateAnchorPropertiesAsync(anchor);
    }

Ustaw wygaśnięcie

Istnieje również możliwość skonfigurowania kotwicy tak, aby wygasała automatycznie w danej dacie w przyszłości. Gdy kotwica wygaśnie, nie będzie już znajdować się ani aktualizować. Wygaśnięcie można ustawić tylko po utworzeniu kotwicy przed zapisaniem jej w chmurze. Aktualizowanie wygasania później nie jest możliwe. Jeśli podczas tworzenia kotwicy nie ustawiono żadnego wygaśnięcia, kotwica wygaśnie tylko po ręcznym usunięciu.

Dowiedz się więcej o właściwości Expiration .

    cloudAnchor.Expiration = DateTimeOffset.Now.AddDays(7);

Lokalizowanie kotwicy przestrzennej chmury

Możliwość zlokalizowania wcześniej zapisanej kotwicy przestrzennej chmury jest jedną z głównych przyczyn korzystania z usługi Azure Spatial Anchors. W tym celu używamy "Obserwatorów". W danym momencie można używać tylko jednego obserwatora; wielu obserwatorów nie jest obsługiwanych. Istnieje kilka różnych sposobów (nazywanych również strategiami lokalizowania zakotwiczenia) obserwator może zlokalizować kotwicę przestrzenną chmury. Możesz użyć jednej strategii na obserwatorze naraz.

Uwaga

Za każdym razem, gdy znajdziesz kotwicę, usługa Azure Spatial Anchors podejmie próbę użycia zebranych danych środowiska w celu rozszerzenia informacji wizualnych na kotwicy. Jeśli masz problemy z lokalizowaniem kotwicy, warto utworzyć kotwicę, a następnie zlokalizować ją kilka razy z różnych kątów i warunków oświetlenia.

Jeśli lokalizujesz kotwice przestrzenne chmury według identyfikatora, możesz przechowywać identyfikator zakotwiczenia przestrzennego w chmurze w usłudze zaplecza aplikacji i udostępnić go wszystkim urządzeniom, które mogą je prawidłowo uwierzytelniać. Aby zapoznać się z tym przykładem, zobacz Samouczek: udostępnianie kotwic przestrzennych między urządzeniami.

Utwórz wystąpienie AnchorLocateCriteria obiektu, ustaw identyfikatory, których szukasz, i wywołaj metodę CreateWatcher w sesji, podając element AnchorLocateCriteria.

Dowiedz się więcej o metodzie CreateWatcher .

    AnchorLocateCriteria criteria = new AnchorLocateCriteria();
    criteria.Identifiers = new string[] { @"id1", @"id2", @"id3" };
    this.cloudSession.CreateWatcher(criteria);

Po utworzeniu obserwatora AnchorLocated zdarzenie zostanie wyzwolone dla każdej żądanej kotwicy. To zdarzenie jest uruchamiane, gdy znajduje się kotwica lub jeśli nie można znaleźć kotwicy. Jeśli taka sytuacja się stanie, przyczyna zostanie podana w stanie . Po przetworzeniu wszystkich kotwic dla obserwatora, znalezieniu lub nieponalezieniu zdarzenia LocateAnchorsCompleted zdarzenie zostanie wyzwolony. Istnieje limit 35 identyfikatorów na obserwatora.

Dowiedz się więcej na temat delegata AnchorLocatedDelegate .

    this.cloudSession.AnchorLocated += (object sender, AnchorLocatedEventArgs args) =>
    {
        switch (args.Status)
        {
            case LocateAnchorStatus.Located:
                CloudSpatialAnchor foundAnchor = args.Anchor;
                // Go add your anchor to the scene...
                break;
            case LocateAnchorStatus.AlreadyTracked:
                // This anchor has already been reported and is being tracked
                break;
            case LocateAnchorStatus.NotLocatedAnchorDoesNotExist:
                // The anchor was deleted or never existed in the first place
                // Drop it, or show UI to ask user to anchor the content anew
                break;
            case LocateAnchorStatus.NotLocated:
                // The anchor hasn't been found given the location data
                // The user might in the wrong location, or maybe more data will help
                // Show UI to tell user to keep looking around
                break;
        }
    }

Usuwanie kotwic

Usuwanie kotwic, gdy nie jest już używane, jest dobrym rozwiązaniem, które należy uwzględnić na wczesnym etapie procesu programowania i praktyk, aby zachować czyszczenie zasobów platformy Azure.

Dowiedz się więcej o metodzie DeleteAnchorAsync .

    await this.cloudSession.DeleteAnchorAsync(cloudAnchor);
    // Perform any processing you may want when delete finishes

Usuwanie kotwicy bez lokalizowania

Jeśli nie możesz zlokalizować kotwicy, ale nadal chcesz go usunąć, możesz użyć interfejsu GetAnchorPropertiesAsync API, który przyjmuje identyfikator anchorId jako dane wejściowe, aby uzyskać CloudSpatialAnchor obiekt. Następnie możesz przekazać ten obiekt do DeleteAnchorAsync , aby go usunąć.

var anchor = await cloudSession.GetAnchorPropertiesAsync(@"anchorId");
await this.cloudSession.DeleteAnchorAsync(anchor);

Wstrzymywanie, resetowanie lub zatrzymywanie sesji

Aby tymczasowo zatrzymać sesję, możesz wywołać metodę Stop(). Spowoduje to zatrzymanie wszystkich obserwatorów i przetwarzania środowiska, nawet jeśli wywołasz metodę ProcessFrame(). Następnie można wywołać Start() polecenie w celu wznowienia przetwarzania. Podczas wznawiania dane środowiska przechwytywane w sesji są zachowywane.

Dowiedz się więcej o metodzie Stop .

    this.cloudSession.Stop();

Aby zresetować dane środowiska przechwycone w sesji, możesz wywołać metodę Reset().

Dowiedz się więcej o metodzie Reset .

    this.cloudSession.Reset();

Aby prawidłowo wyczyścić po sesji, wywołaj metodę Dispose().

Dowiedz się więcej o metodzie Dispose .

    this.cloudSession.Dispose();

Następne kroki

W tym przewodniku przedstawiono sposób tworzenia i lokalizowania kotwic przy użyciu zestawu SDK usługi Azure Spatial Anchors. Aby dowiedzieć się więcej na temat relacji kotwicy, przejdź do następnego przewodnika.