Vytvoření a vyhledání ukotvení pomocí Azure Spatial Anchors v Unity

Azure Spatial Anchors umožňuje sdílet kotvy na světě mezi různými zařízeními. Podporuje několik různých vývojových prostředí. V tomto článku se podíváme na to, jak používat sadu Azure Spatial Anchors SDK v Unity k:

  • Správně nastavte a spravujte relaci Azure Spatial Anchors.
  • Vytvořte a nastavte vlastnosti v místních ukotveních.
  • Nahrajte je do cloudu.
  • Vyhledejte a odstraňte cloudové prostorové kotvy.

Požadavky

K dokončení této příručky se ujistěte, že máte:

Cross Platform

Inicializace relace

Hlavním vstupním bodem sady SDK je třída představující vaši relaci. Obvykle deklarujete pole ve třídě, které spravuje vaši relaci zobrazení a nativní rozšířené reality.

Přečtěte si další informace o třídě CloudSpatialAnchorSession .

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

Nastavení ověřování

Pokud chcete získat přístup ke službě, musíte zadat klíč účtu, přístupový token nebo ověřovací token Microsoft Entra. Další informace najdete také na stránce Koncept ověřování.

Klíče účtu

Klíče účtu jsou přihlašovací údaje, které vaší aplikaci umožňují ověřovat se službou Azure Spatial Anchors. Zamýšleným účelem klíčů účtu je pomoct vám rychle začít. Zejména během fáze vývoje integrace vaší aplikace s Azure Spatial Anchors. Klíče účtu můžete použít tak, že je během vývoje vložíte do klientských aplikací. Při pokroku nad rámec vývoje se důrazně doporučuje přejít na ověřovací mechanismus, který je produkční, podporovaný přístupovými tokeny nebo ověřováním uživatelů Microsoft Entra. Pokud chcete získat klíč účtu pro vývoj, navštivte svůj účet Azure Spatial Anchors a přejděte na kartu Klíče.

Přečtěte si další informace o třídě SessionConfiguration .

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

Přístupové tokeny

Přístupové tokeny představují robustnější metodu ověřování pomocí Azure Spatial Anchors. Zvláště při přípravě aplikace na produkční nasazení. Shrnutím tohoto přístupu je nastavení back-endové služby, pomocí které se klientská aplikace může bezpečně ověřit. Rozhraní back-endové služby s AAD za běhu a se službou zabezpečených tokenů Azure Spatial Anchors za účelem vyžádání přístupového tokenu. Tento token se pak doručí do klientské aplikace a použije se v sadě SDK k ověření pomocí Azure Spatial Anchors.

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

Pokud přístupový token není nastavený, musíte zpracovat TokenRequired událost nebo implementovat metodu tokenRequired v delegovacím protokolu.

Událost můžete zpracovat synchronně nastavením vlastnosti argumentů události.

Přečtěte si další informace o delegátu TokenRequiredDelegate .

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

Pokud potřebujete spustit asynchronní práci v obslužné rutině, můžete odložit nastavení tokenu vyžádáním objektu deferral a jeho dokončením, jako v následujícím příkladu.

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

Ověřování Microsoft Entra

Azure Spatial Anchors také umožňuje aplikacím ověřovat pomocí tokenů Microsoft Entra ID (Active Directory). K integraci s Azure Spatial Anchors můžete například použít tokeny Microsoft Entra. Pokud podnik udržuje uživatele v Microsoft Entra ID, můžete zadat token Microsoft Entra v sadě Azure Spatial Anchors SDK. Díky tomu se můžete ověřit přímo ve službě Azure Spatial Anchors pro účet, který je součástí stejného tenanta Microsoft Entra.

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

Stejně jako u přístupových tokenů platí, že pokud není nastavený token Microsoft Entra, musíte zpracovat událost TokenRequired nebo implementovat metodu tokenRequired v delegovacím protokolu.

Událost můžete zpracovat synchronně nastavením vlastnosti argumentů události.

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

Pokud potřebujete spustit asynchronní práci v obslužné rutině, můžete odložit nastavení tokenu vyžádáním objektu deferral a jeho dokončením, jako v následujícím příkladu.

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

Nastavení relace

Vyvolá se, Start() aby relace mohla zpracovávat data prostředí.

Pokud chcete zpracovat události vyvolané relací, připojte obslužnou rutinu události.

Přečtěte si další informace o metodě 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();

Poskytnutí rámců do relace

Relace prostorového ukotvení funguje namapováním prostoru kolem uživatele. To vám pomůže určit, kde se kotvy nacházejí. Mobilní platformy (iOS &Android) vyžadují nativní volání kanálu fotoaparátu k získání snímků z knihovny ar vaší platformy. Naproti tomu HoloLens neustále kontroluje prostředí, takže není potřeba provádět konkrétní volání jako na mobilních platformách.

Přečtěte si další informace o metodě 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

Poskytnutí zpětné vazby uživateli

Můžete napsat kód pro zpracování aktualizované události relace. Tato událost se aktivuje pokaždé, když relace zlepšuje pochopení vašeho okolí. To vám umožní:

  • UserFeedback Pomocí třídy můžete uživateli poskytnout zpětnou vazbu při přesouvání zařízení a relace aktualizuje své znalosti prostředí. Chcete-li to provést,
  • Určete, v jakém okamžiku je dostatek sledovaných prostorových dat k vytvoření prostorových ukotvení. Určíte to pomocí nebo ReadyForCreateProgressRecommendedForCreateProgress. Jakmile ReadyForCreateProgress je nad 1, máme dostatek dat k uložení cloudové prostorové ukotvení, ale doporučujeme počkat, až RecommendedForCreateProgress bude nad 1, abyste to udělali.

Přečtěte si další informace o delegátu 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.#%}";
    };

Vytvoření cloudové prostorové ukotvení

Pokud chcete vytvořit cloudové prostorové ukotvení, nejprve vytvoříte ukotvení v systému rozšířené reality vaší platformy a pak vytvoříte cloudový protějšek. Použijete metodu CreateAnchorAsync() .

Přečtěte si další informace o třídě 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 je popsáno výše, potřebujete dostatek dat prostředí zachycených před pokusem o vytvoření nového cloudového prostorového ukotvení. To znamená ReadyForCreateProgress , že musí být vyšší než 1, ale doporučujeme počkat na to, než RecommendedForCreateProgress je 1.

Přečtěte si další informace o metodě GetSessionStatusAsync .

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

Nastavení vlastností

Při ukládání cloudových prostorových ukotvení můžete přidat některé vlastnosti. Stejně jako typ uloženého objektu nebo základní vlastnosti, jako je to, jestli má být povolena pro interakci. To může být užitečné při zjišťování: objekt můžete okamžitě vykreslit pro uživatele, například rámeček obrázku s prázdným obsahem. Pak se na pozadí zobrazí další podrobnosti o stavu, například obrázek, který se má zobrazit v rámečku.

Přečtěte si další informace o vlastnosti AppProperties .

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

Aktualizace vlastností

Chcete-li aktualizovat vlastnosti ukotvení, použijte metodu UpdateAnchorProperties() . Pokud se dvě nebo více zařízení pokusí aktualizovat vlastnosti pro stejnou ukotvení najednou, použijeme model optimistické souběžnosti. To znamená, že první zápis vyhraje. Všechny ostatní zápisy se zobrazí chyba Concurrency: Před dalším pokusem by bylo potřeba aktualizovat vlastnosti.

Přečtěte si další informace o metodě UpdateAnchorPropertiesAsync .

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

Umístění ukotvení po vytvoření ve službě nejde aktualizovat – musíte vytvořit novou ukotvení a odstranit starý, abyste mohli sledovat novou pozici.

Pokud nepotřebujete najít ukotvení pro aktualizaci jeho vlastností, můžete použít metodu GetAnchorPropertiesAsync()CloudSpatialAnchor , která vrací objekt s vlastnostmi.

Přečtěte si další informace o metodě GetAnchorPropertiesAsync .

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

Nastavit vypršení platnosti

V budoucnu je také možné nakonfigurovat, aby platnost ukotvení automaticky vypršela v daném datu. Když vyprší platnost ukotvení, nebude se už nacházet ani aktualizovat. Vypršení platnosti je možné nastavit pouze při vytvoření ukotvení před uložením do cloudu. Aktualizace vypršení platnosti později není možná. Pokud během vytváření ukotvení není nastavené žádné vypršení platnosti, platnost ukotvení vyprší pouze při ručním odstranění.

Přečtěte si další informace o vlastnosti Vypršení platnosti .

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

Vyhledání cloudové prostorové ukotvení

Schopnost najít dříve uložené cloudové prostorové ukotvení je jedním z hlavních důvodů použití Azure Spatial Anchors. K tomu používáme "Watchers". Můžete použít pouze jeden Watcher najednou; více sledovacích procesů není podporováno. Sledovací proces může najít cloudové prostorové ukotvení několika různými způsoby (označovaných také jako Strategie hledání ukotvení). Na sledovacím nástroji můžete současně použít jednu strategii.

  • Vyhledejte kotvy podle identifikátoru.
  • Vyhledejte kotvy připojené k dříve umístěné ukotvení. Tady se dozvíte o relacích ukotvení.
  • Vyhledejte kotvu pomocí hrubé relokalizace.

Poznámka:

Při každém vyhledání ukotvení se Azure Spatial Anchors pokusí použít data prostředí shromážděná k rozšíření vizuálních informací na ukotvení. Pokud máte potíže s vyhledáním kotvy, může být užitečné vytvořit kotvu a pak ji několikrát vyhledat z různých úhlů a světelných podmínek.

Pokud lokalizujete cloudové prostorové kotvy podle identifikátoru, můžete uložit identifikátor cloudové prostorové ukotvení v back-endové službě vaší aplikace a zpřístupnit ho všem zařízením, která se u ní můžou správně ověřit. Příklad najdete v tématu Kurz: Sdílení prostorových ukotvení napříč zařízeními.

Vytvořte instanci objektuAnchorLocateCriteria, nastavte identifikátory, které hledáte, a vyvoláte metodu CreateWatcher v relaci zadáním .AnchorLocateCriteria

Přečtěte si další informace o metodě CreateWatcher .

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

Po vytvoření sledovacího nástroje se AnchorLocated událost aktivuje pro každou požadovanou ukotvení. Tato událost se aktivuje, když se nachází ukotvení nebo pokud se ukotvení nedá najít. Pokud k této situaci dojde, bude důvod uveden ve stavu. Po zpracování, nalezení nebo nenalezení LocateAnchorsCompleted všech ukotvení sledovacího prvku se událost aktivuje. Počet identifikátorů na sledovací proces je omezený na 35 identifikátorů.

Přečtěte si další informace o delegátu 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;
        }
    }

Odstranění ukotvení

Odstranění ukotvení, když už se nepoužívá, je vhodné zahrnout do procesu a postupů vývoje včas, aby se vaše prostředky Azure vyčistily.

Přečtěte si další informace o metodě DeleteAnchorAsync .

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

Odstranění ukotvení bez vyhledání

Pokud nemůžete najít kotvu, ale přesto ji chcete odstranit, můžete k získání objektu CloudSpatialAnchor použít GetAnchorPropertiesAsync rozhraní API, které jako vstup převezme anchorId. Tento objekt pak můžete předat, abyste DeleteAnchorAsync ho odstranili.

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

Pozastavení, resetování nebo zastavení relace

Pokud chcete relaci dočasně zastavit, můžete vyvolat Stop(). Tím zastavíte zpracování všech sledovacích procesů a prostředí, a to i v případě, že vyvoláte ProcessFrame(). Potom můžete vyvolat Start() obnovení zpracování. Při obnovení se zachytávají data prostředí, která jsou v relaci zaznamenána.

Přečtěte si další informace o metodě Stop .

    this.cloudSession.Stop();

Chcete-li obnovit data prostředí zachycená ve vaší relaci, můžete vyvolat Reset().

Přečtěte si další informace o metodě Reset.

    this.cloudSession.Reset();

Chcete-li správně vyčistit po relaci, vyvolejte Dispose().

Přečtěte si další informace o metodě Dispose .

    this.cloudSession.Dispose();

Další kroky

V této příručce jste se dozvěděli, jak vytvořit a najít ukotvení pomocí sady Azure Spatial Anchors SDK. Další informace o relacích ukotvení najdete v další příručce.