Android XR

Progettazione di contenuti spaziali su Android XR con Unity

Altoparlanti

  • Levana Chen

    Software Engineer

  • Jennifer Stanton

    Senior Software Engineer

Informazioni

Informazioni sulla presentazione

Scopri come ancorare e rendere persistenti le esperienze 3D nel mondo reale utilizzando Unity e Android XR. Questa sessione illustra il framework Spatial Entities, gli ancoraggi cloud e le API Geospatial, mostrando come creare app sensibili al contesto che ricordano i posizionamenti fisici e sincronizzano i dati spaziali multiutente tra le sessioni.

Esamineremo l'architettura alla base delle entità spaziali e capiremo come ancorare gli asset digitali a oggetti fisici, superfici e posizioni geografiche. Imparerai a utilizzare flussi di lavoro Unity pratici per mappare gli spazi, mantenere i contenuti tra le sessioni e creare esperienze AR/XR condivise e basate sulla posizione.

Riepilogo

  • AR Foundation fornisce un'API di scripting unificata per le piattaforme XR utilizzando le estensioni OpenXR. Ti consente di rappresentare ed eseguire query su elementi del mondo reale, come piani e mesh.
  • Le ancora persistenti stabilizzano i contenuti digitali tra le sessioni e i riavvii del dispositivo. Puoi renderli persistenti con TrySaveAnchorAsync e ricaricarli utilizzando i GUID serializzati.
  • Il framework Spatial Entities sostituisce le estensioni tracciabili per fornire supporto multipiattaforma e prestazioni migliori per il monitoraggio di elementi come riquadri di delimitazione e indicatori.
  • I componenti di gestione devono essere disattivati finché non vengono concesse le autorizzazioni di Android XR. In questo modo si evitano errori di inizializzazione del sottosistema causati dall'accesso limitato ai dati sensibili dell'ambiente.
  • L'API Geospatial utilizza i servizi ARCore di Google Cloud e il VPS per posizionare i contenuti in luoghi reali all'aperto.

Risorse

Gemini Notebook

Argomenti

  • android-xr
  • unità
  • ar-foundation
  • openxr
  • spatial-entities
  • annunci di ancoraggio
  • geospatial-api

Trascrizione

Scarica la trascrizione

Introduzione e panoramica di AR Foundation

  • Okay.

  • Ciao a tutti.

  • Questo è "Progettare contenuti spaziali su Android XR con Unity".

  • Mi chiamo Jennifer Stanton.

  • Lavoro presso Unity come Senior Software Engineer.

  • Lavoro nel team XR Features, in particolare su AR Foundation e sui pacchetti correlati che portano la realtà aumentata e mista su Unity.

  • Sono Levana Chen del team di motori grafici XR di Google.

  • I nostri team si sono concentrati sulla fornitura di plug-in e pacchetti per offrire funzionalità XR avanzate e integrazioni perfette con i motori grafici.

  • Una delle sfide più grandi che ci segnalate è che supportare più piattaforme XR con lo stesso codebase richiede molto lavoro.

  • AR Foundation è il livello API di realtà estesa di alto livello di Unity.

  • Puoi scegliere come target più piattaforme XR senza dover riscrivere il codice in modo significativo o gestire più codebase. Inoltre, hai a disposizione un'unica API di scripting per le funzionalità AR su qualsiasi piattaforma.

  • In questo modo, puoi concentrarti sulla creazione della tua app, del tuo gioco o della tua esperienza, mentre Unity si occupa dei dettagli della piattaforma per te.

  • Un modo in cui AR Foundation raggiunge questo obiettivo è tramite le estensioni OpenXR.

  • Si tratta di un insieme di API aperte e standard di settore definite dal Khronos Group.

  • Anche OpenXR ha creato entità spaziali.

  • È un framework per i contenuti digitali che consente di rappresentare il mondo fisico e interagire con questo.

  • Le entità spaziali forniscono un modello unificato per rappresentare gli elementi del mondo reale come oggetti digitali.

  • Sono felice di condividere con te alcune delle ultime informazioni su AR Foundation, così potrai iniziare il tuo percorso per creare esperienze per XR.

  • Successivamente, esaminerò le funzionalità di AR Foundation in modo che i tuoi contenuti digitali possano interagire con il mondo reale.

  • Poi esaminerò la configurazione del progetto, inclusi i pacchetti e altre dipendenze, in modo che tu possa implementarla nei tuoi progetti.

  • Infine, concluderò esaminando alcune funzionalità esclusive di Android XR.

Funzionalità principali di AR Foundation

  • Alcuni dei modi in cui AR Foundation rappresenta digitalmente il mondo reale sono i piani.

  • Si tratta di superfici piane nell'ambiente fisico, come pavimenti, pareti, soffitti e persino tavoli e divani.

  • Le mesh sono strutture 3D che rappresentano la geometria del mondo fisico.

  • Inoltre, abbiamo anche modi per interagire con il mondo reale, i raycast.

  • Questi determinano il punto in cui un raggio interseca i contenuti digitali.

  • Immaginalo come un puntatore laser e riceverai informazioni su dove sta puntando.

  • Abbiamo anche le ancore, che aiutano a stabilizzare e riposizionare un punto nello spazio.

  • Approfondirò l'argomento delle ancore più avanti in questa presentazione.

  • Quindi, tutte e quattro sono considerate funzionalità di AR Foundation.

  • Esistono anche altre funzionalità che non sono menzionate in questa slide.

  • In particolare, i piani e gli ancoraggi sono considerati tracciabili poiché estendono la classe ARTrackable e i relativi gestori monitorano gli aggiornamenti dal runtime.

  • Quindi, passiamo agli aerei.

  • Per i piani, abbiamo il componente ARPlane, che fornisce l'identificazione in tempo reale delle superfici piane.

  • Hanno etichette semantiche su cui puoi eseguire query per sapere se il piano è un pavimento, un tavolo, una parete e così via.

  • I piani hanno anche confini dinamici, quindi, man mano che l'utente si muove nel mondo reale e può vedere più superfici, i confini dei piani si espandono, si uniscono e si perfezionano dinamicamente in tempo reale.

  • Possiamo anche collegare un collisore mesh al piano per gestire la fisica.

  • Qui puoi vedere un esempio di rilevamento di un piano.

  • Questa è la scena di raycast degli esempi di AR Foundation in esecuzione su un dispositivo Android XR.

  • Rileva poligoni 2D dinamici in tempo reale.

  • Puoi creare un'app con questa funzionalità seguendo la nostra guida alla configurazione del progetto o utilizzando uno dei nostri esempi o modelli.

  • Poi abbiamo le mesh.

  • Le mesh sono una funzionalità AR che fornisce mesh 3D dell'ambiente.

  • Possiamo collegare un collider mesh a queste mesh generate, consentendo ai tuoi contenuti digitali di interagire con gli oggetti del mondo reale.

  • Le mesh consentono un'occlusione degli oggetti convincente.

  • In questo modo, un oggetto virtuale può apparire dietro un oggetto fisico.

  • Se l'oggetto digitale può muoversi nello spazio, puoi utilizzare la stessa geometria per trovare un percorso che eviti gli oggetti del mondo reale.

  • Poi abbiamo il ray casting.

  • Il ray casting proietta raggi virtuali nella scena 3D per cercare intersezioni senza che tu debba preoccuparti di calcoli matematici complessi.

  • Il raggio proiettato potrebbe intersecare più oggetti 3D nell'ambiente.

  • Puoi configurare il raycast in modo che colpisca solo determinati tipi di contenuti digitali.

  • Ad esempio, puoi configurarlo in modo che non colpisca i piani e si intersechi solo con le mesh.

Configurazione di pacchetti e dipendenze

  • Ora diamo un'occhiata ai pacchetti pertinenti.

  • Tutti questi pacchetti collaborano per comunicare tra loro e creare un'esperienza XR completa.

  • Come accennato, AR Foundation gestisce funzionalità come piani e ancoraggi.

  • Il plug-in OpenXR gestisce le API native su varie piattaforme XR, quindi ti consigliamo di utilizzare questo pacchetto se il tuo dispositivo utilizza OpenXR.

  • Il plug-in OpenXR può essere facoltativamente accoppiato al pacchetto OpenXR Spatial Entities per accedere in modo specifico alle estensioni di Spatial Entities, di cui parleremo più avanti.

  • Se sai che i tuoi dispositivi target saranno specificamente dispositivi Android XR, come i visori XR e gli occhiali XR con cavo, è necessario il pacchetto Unity OpenXR Android XR.

  • Poiché tutto questo segue il pattern del plug-in, l'impatto sul codice dovrebbe essere minimo.

  • Non tutte le funzionalità sono disponibili in tutti i pacchetti AR Foundation.

  • Ad esempio, se guardi questo grafico, la creazione di mesh non è attualmente disponibile nel pacchetto Unity OpenXR Spatial Entities.

  • XR Plug-in Management ti consente di gestire le funzionalità OpenXR selezionate nel tuo progetto.

  • Quindi, se ti trovi nell'editor di Unity, vai a Edit (Modifica), Project Settings (Impostazioni progetto) e poi XR Plug-in Management (Gestione plug-in XR) nella barra laterale sinistra.

  • Qui puoi trovare le funzionalità e i gruppi di funzionalità di OpenXR, in modo da poter selezionare e deselezionare le funzionalità e i gruppi di funzionalità che vuoi includere nella tua build.

  • Ad esempio, in questo screenshot, vediamo tutte quelle incluse nel pacchetto OpenXR di Android XR.

  • E poi puoi combinarle con entità spaziali, ad esempio, se vuoi.

  • Ecco la finestra di Package Manager.

  • Ho evidenziato alcuni dei pacchetti che potresti vedere in una tipica configurazione di un progetto XR.

  • Come puoi vedere, abbiamo AR Foundation, che è stato menzionato.

  • Abbiamo anche il plug-in OpenXR.

  • Abbiamo il pacchetto Android XR.

  • Ho anche evidenziato alcuni elementi di altre piattaforme, perché puoi sicuramente creare un progetto che viene compilato per più piattaforme.

  • In basso a destra sono presenti anche altri pacchetti.

  • Composition Layers, che funziona con i dispositivi OpenXR; Core Utils, molto utile per tutto ciò che riguarda XR; e poi XR Hands e XR Interaction Toolkit per ottenere l'input, che è piuttosto essenziale.

  • Il passaggio successivo è la convalida del progetto.

  • Quindi, anche questo fa parte di XR Plug-in Management.

  • La convalida del progetto può rilevare funzionalità duplicate e altri problemi nel progetto che devi risolvere per eseguirlo.

  • In questo screenshot, però, ho evidenziato le caratteristiche duplicate.

  • In pratica, questo significa che due delle stesse funzionalità, ad esempio ancoraggi, piani e raycast,

  • L'utente ha scelto di includere duplicati di queste funzionalità da più pacchetti e gli viene chiesto di selezionare l'uno o l'altro.

Ancoraggi locali e persistenza

  • Questo ci porta alle ancora locali e alla persistenza.

  • Le ancora assicurano che i contenuti digitali rimangano nelle posizioni desiderate nell'ambiente, indipendentemente dalle modifiche allo stato di monitoraggio della sessione AR.

  • Le piattaforme AR aggiornano automaticamente le posizioni delle ancora nel tempo per garantire che rimangano in una posizione coerente e le ancore sono il modo migliore per assicurarti che i tuoi contenuti rimangano in posizione se ti allontani dall'ancora e poi torni indietro.

  • E cosa succede quando l'utente chiude l'app, la riavvia in un secondo momento e torna a utilizzarla in una sessione separata?

  • Le ancora persistenti ti consentono di salvare le ancora in una sessione AR e di caricarle nelle sessioni successive.

  • Sopravvivono ai cicli di vita delle app e ai riavvii dei dispositivi.

  • Qui è raffigurato il nostro esempio di ancoraggi persistenti nel progetto AR Foundation Samples.

  • La scena di esempio ha un menu con tutte le funzionalità supportate su quella piattaforma, come il salvataggio e il caricamento delle ancora.

  • E questo ci porta al ciclo di vita delle ancora persistenti.

  • Innanzitutto, devi creare un ancoraggio localmente, in modo che non venga ancora salvato da nessuna parte, non nell'archiviazione permanente, ma solo un ancoraggio locale.

  • e poi li rendi persistenti nello spazio di archiviazione.

  • Dopodiché, puoi riavviare l'app e caricarla dallo spazio di archiviazione.

  • Alcune piattaforme, tra cui Android XR, supportano anche la cancellazione o l'annullamento della persistenza delle ancora.

  • Il provider di entità spaziali supporta il caricamento automatico di tutte le ancora salvate, in modo da non dover richiedere manualmente ogni ancora tramite il relativo ID.

  • Nelle impostazioni di XR Plug-in Management, puoi selezionare l'opzione Automatically Load Saved Anchors (Carica automaticamente gli anchor salvati) nella funzionalità Spatial Entities: Anchors (Entità spaziali: anchor).

  • Per salvare un'ancora bastano poche righe di codice.

  • Per prima cosa, iniziamo nell'editor di Unity e ci assicuriamo che la scena sia pronta aggiungendo il componente AR Anchor Manager al tuo oggetto di gioco XR Origin.

  • Il gestore mantiene la scena aggiornata con le ancora tracciate dal runtime.

  • Questo ci porta al codice.

  • Per aggiungere un'ancora, puoi semplicemente chiamare TryAddAnchorAsync e passare la posa della posizione in cui vuoi posizionare l'ancora.

    async void CreateAnchorAsync(ARAnchorManager manager, Pose pose) {
        var result = await manager.TryAddAnchorAsync(pose);
        if (result.status.IsError()) {
            // handle error
            return;
        }
        var anchor = result.value;
    }
  • Ora vediamo come rimuovere gli ancoraggi.

    void RemoveAnchor(ARAnchorManager manager, ARAnchor anchor) {
        var result = manager.TryRemoveAnchor(anchor.trackableId);
        if (result.status.IsError()) {
            // handle error
            return;
        }
    }
    
    void DestroyAnchorComponent(ARAnchor anchor) {
        Destroy(anchor);
    }
  • Anche in questo caso, si tratta praticamente di una sola riga di codice.

  • Chiami TryRemoveAnchor e passi l'ID tracciabile dell'ancoraggio.

  • Quando è stato creato, all'ancoraggio è già stato assegnato un ID tracciabile.

  • E poi abbiamo TrySaveAnchorAsync.

    async void SaveAnchorAsync(ARAnchorManager manager, ARAnchor anchor) {
        var result = await manager.TrySaveAnchorAsync(anchor);
        if (result.status.IsError()) {
            // handle error
            return;
        }
    
        // Save this value, then return it as an input parameter
        SerializableGuid guid = result.value;
    }
  • Passi un'ancora AR come input.

  • Questa funzione restituisce un SerializableGuid che identifica l'ancoraggio nello spazio di archiviazione permanente.

  • In un secondo momento, puoi utilizzare il GUID durante il caricamento dell'ancoraggio.

  • E questo ci porta agli ancoraggi di caricamento.

    async void LoadAnchorAsync(ARAnchorManager manager, SerializableGuid guid) {
        var result = await manager.TryLoadAnchorAsync(guid);
        if (result.status.IsError()) {
            // handle error
            return;
        }
    
        ARAnchor anchor = result.value;
    }
  • La funzione da chiamare qui è TryLoadAnchorAsync e devi passare il GUID serializzato di prima.

  • Come risultato, restituirà un'ancora AR.

  • Questo è tutto.

  • Queste funzioni ti consentono di gestire facilmente sia gli ancoraggi locali che quelli persistenti.

  • Pertanto, il monitoraggio degli ancoraggi è un'attività piuttosto costosa sulla maggior parte delle piattaforme AR.

  • Quando lavori con gli ancoraggi, tieni presente le seguenti best practice: evita di creare più ancoraggi molto vicini tra loro, valuta se puoi utilizzare un ancoraggio vicino invece di crearne un altro, rimuovi gli ancoraggi quando non li utilizzi più e, infine, se attivi un'altra funzionalità AR per calcolare la posa desiderata per un ancoraggio, valuta se puoi disattivarla una volta creato l'ancoraggio.

  • Ora passo la parola a Levana.

SDK Android XR per Unity

  • Grazie, Jennifer.

  • Ora, vorrei illustrarti il contributo di Google al percorso di Android XR in Unity.

  • Quindi, oltre ai plug-in Unity OpenXR che Jennifer ha presentato finora, Google fornisce l'SDK Android XR per Unity con funzionalità aggiuntive disponibili sulla piattaforma Android XR.

  • Questo SDK contiene molte funzionalità e pacchetti e, in questo intervento, ci concentreremo sul pacchetto Android XR Extension per Unity.

  • Quindi, analogamente a OpenXR Android XR e OpenXR Spatial Entities, il pacchetto Android XR Extension for Unity è in realtà un provider OpenXR.

  • L'architettura di questo pacchetto è la seguente e i componenti possono funzionare in parallelo o in modo indipendente.

  • Quindi, come tutti gli altri provider OpenXR, il pacchetto di Google si basa direttamente sull'interfaccia OpenXR standard.

  • Qui mostriamo una serie di funzionalità per un confronto con tutti gli altri provider.

  • In questo modo, puoi prendere una decisione su quando e perché scegliere un tipo rispetto a un altro.

  • Potresti avere una domanda sul tracciabile e sull'indicatore di entità spaziale mostrato in questa tabella.

  • Ecco una nota a margine: per chi ha già creato app ed esperienze su Android XR, abbiamo fornito queste funzionalità tramite le estensioni tracciabili, che funzionano solo su Android XR.

  • In seguito, come ha detto Jennifer, abbiamo lavorato come gruppo aperto OpenXR e poi abbiamo rilasciato l'estensione Spatial Entities sulla destra e fornito un'esperienza coerente e multipiattaforma.

  • Al momento, stiamo ritirando l'estensione tracciabile a favore del framework Spatial Entities.

  • Non solo quest'ultimo è molto più performante, ma offre anche il supporto multipiattaforma.

Creazione con entità spaziali

  • Diamo un'occhiata più da vicino alle entità spaziali.

  • Quindi, oltre a quanto menzionato da Jennifer su piani, ray casting e ancoraggi, puoi trovare questa funzionalità supportata anche dai fornitori di entità spaziali, come i marcatori, che possono rilevare e decodificare i codici a barre 2D standard e monitorare la loro posizione nello spazio 3D, e l'immagine riconoscerà la grafica 2D nota e la monitorerà nello spazio 3D.

  • Poi il riquadro di delimitazione, che identificherà l'oggetto fisico, come la tastiera, il laptop o il mouse, e monitorerà il riquadro di delimitazione nella posa 3D.

  • Nel prossimo esempio, configureremo la funzionalità del riquadro di delimitazione fornita dal pacchetto Extensions di Google.

  • Questa visualizzazione è praticamente la stessa per tutte le funzionalità OpenXR.

  • Quindi, devi prima passare alla piattaforma Android XR, poi attivare il provider OpenXR e selezionare la funzionalità OpenXR con cui vuoi eseguire la build, ad esempio la funzionalità del riquadro di delimitazione dell'entità spaziale mostrata qui, e infine correggere i problemi di convalida del progetto.

  • Ti aiuterà a trovare tutte le dipendenze richieste da una determinata funzionalità e quindi a risolvere i conflitti causati da più funzionalità che contribuiscono allo stesso sottosistema.

  • A volte, nella maggior parte dei casi, devi scegliere una sola funzionalità se vuoi utilizzare, ad esempio, l'ancoraggio, il piano o il riquadro di delimitazione qui.

  • Infine, puoi semplicemente creare la scena di esempio o la scena di test.

  • Per accedere all'oggetto tracciabile in fase di esecuzione, puoi semplicemente aggiungere il componente AR Bounding Box Manager, che è simile ad AR Anchor Manager, e poi utilizzare l'interfaccia AR Foundation per accedervi.

  • In alternativa, puoi anche importare l'esempio di entità spaziale fornito dal nostro pacchetto di estensione come modello da cui iniziare.

  • Ecco la differenza principale quando utilizzi la funzionalità AR Foundation su Android XR.

  • Per comprendere l'ambiente circostante l'utente, l'app di solito deve accedere ai dati sensibili relativi all'ambiente.

  • Per proteggere l'utente, Android XR limita l'accesso ai dati del sistema dietro le autorizzazioni.

  • Potresti già avere familiarità con questo, come la normale chiamata di autorizzazione di Android, ad esempio l'accesso alla fotocamera o alla posizione e così via.

  • La best practice in questo caso è disattivare il componente manager all'avvio, dall'editor, come puoi vedere sul lato destro, o dallo script, ad esempio l'evento Awake.

    void Awake() {
        planeManager = GetComponent<ARPlaneManager>();
        planeManager.enabled = false;
        boundingBoxManager = GetComponent<ARBoundingBoxManager>();
        boundingBoxManager.enabled = false;
        permissionUtil = GetComponent<AndroidXRPermissionUtil>();
    }
    
    void OnEnable() {
        StartCoroutine(WaitForPermissions());
    }
  • Una volta concesse tutte le autorizzazioni richieste, puoi attivare il gestore dallo script, come fa l'helper WaitForPermissions qui.

    IEnumerator WaitForPermissions() {
        planeManager.enabled = false;
        boundingBoxManager.enabled = false;
    
        yield return new WaitUntil(() =>
            permissionUtil.AllPermissionGranted());
    
        // Enable after granted permissions and
        // restart subsystems.
        planeManager.enabled = true;
        boundingBoxManager.enabled = true;
    
        // Save permission status.
        permissionGranted = true;
    }
  • In questo modo, puoi evitare un errore di inizializzazione del sottosistema causato da autorizzazioni insufficienti.

  • Questa è una funzionalità speciale.

  • Come ha spiegato Jennifer, l'ancoraggio utilizza AR Foundation. Per espandere la funzionalità di ancoraggio su Android XR, il nostro pacchetto fornisce anche una nuova funzionalità chiamata ancoraggi condivisibili.

  • Questa funzionalità replica ciò che la funzionalità di ancoraggio di AR Foundation attualmente supporta e include anche alcune funzionalità aggiuntive, come le ancoraggi geospaziali.

  • E, come puoi immaginare, l'ancora è il vero ponte che collega il mondo virtuale e quello fisico.

  • Jennifer ci ha spiegato come creare, salvare e caricare gli ancoraggi, ma tutto questo è avvenuto in uno spazio locale, come il salotto dell'utente.

  • E il resto del mondo?

  • E come potremmo condividerla tra di noi?

API Geospatial

  • Ed è qui che entra in gioco l'API Geospatial.

  • Ti consente di creare un'ancora geospaziale basata su una posizione reale, come la tua libreria preferita o un punto di ritrovo in un grande parco.

  • Pertanto, l'API Geospatial può fornirti un tracker di geoposizionamento accurato tramite VPS, noto anche come sistema di posizionamento virtuale, come un GPS, ma utilizza i dati di Street View esterni per fornire risultati di monitoraggio molto più accurati.

  • Alcuni di voi potrebbero già avere familiarità con questa visualizzazione se hanno già utilizzato la funzionalità geospaziale di ARCore.

  • Quindi, per accedere all'API Geospatial su Android XR, dobbiamo prima connetterci al backend ospitato sulla piattaforma Google Cloud.

  • Poiché il backend geospaziale è effettivamente basato sul servizio ARCore su Google Cloud, puoi seguire esattamente lo stesso passaggio per configurare il tuo progetto cloud Google con l'accesso all'API ARCore.

  • Tutto questo consentirà l'utilizzo della funzionalità Google Cloud di Android XR fornita dal nostro pacchetto di estensioni.

  • Una volta abilitata l'API Geospatial e recuperata la chiave API dal progetto Google Cloud, puoi abilitare questa funzionalità e configurare l'autenticazione tramite il menu delle impostazioni di OpenXR mostrato qui e, in alternativa, puoi configurarla manualmente tramite l'API di scripting denominata TrySetAuthenticationAsync.

    async Task TrySetAuthentication() {
        googleCloudFeature =
            OpenXRSettings.Instance
                .GetFeature<XRGoogleCloudFeature>();
        var result = await googleCloudFeature
            .TrySetAuthenticationAsync(
                strategy, credential);
        if (result.IsSuccess()) {
            // Ready to use for geospatial tracker.
        } else if (result.IsUnsupported())  {
            // Google Cloud feature is not supported
        } else if (result.IsKeylessError()) {
            // Confirm if keyless has been set up properly.
        } else {
            // Handling other common OpenXR errors.
        }
    }
  • Tieni presente che al momento la piattaforma Android XR supporta solo l'autenticazione con chiave API, ma in futuro saranno supportate altre credenziali.

  • Quindi, una volta eseguita l'autenticazione, puoi utilizzare un gestore geospaziale per accedere alle funzionalità geospaziali.

  • Prima dell'integrazione, ti consigliamo vivamente di controllare la copertura del VPS su Google Maps.

  • Pertanto, devi avere anche l'accesso alla rete quando utilizzi la funzionalità.

  • XR Geospatial Manager funziona in modo simile al componente AR Session fornito da AR Foundation.

  • Pertanto, è dotato di una proprietà di stato statico per indicare il supporto del sistema e lo stato di monitoraggio del tracker geospaziale.

  • Puoi registrare l'evento di modifica dello stato tramite un callback come questo.

    void OnGeospatialStateChanged(XRGeospatialStateChangedEventArgs eventArgs) {
        bool isInitFailed = eventArgs.CurrState == XRGeospatialState.InitializationFailed;
        if (isInitFailed && XRGeospatialManager.InitializationResult.IsCloudAuthError()) {
            // Handle cloud authentication issues.
        } else if (isInitFailed) {
            // Check XRGeospatialManager.InitializationResult for other common OpenXR errors.
        } else {
            // Iterate runtime state change, and handle accordingly.
        }
    }
    
    private void OnEnable() {
        XRGeospatialManager.OnStateChanged += OnGeospatialStateChanged;
    }
  • Una volta che lo stato geospaziale diventa "In esecuzione", puoi utilizzare questa istanza del gestore per tutte le funzionalità seguenti.

  • Innanzitutto, per verificare la disponibilità di VPS con la posizione GPS specificata, utilizziamo l'API di geolocalizzazione di Unity per ottenere il valore GPS e poi controlliamo la disponibilità di VPS.

    async Task CheckVPSAvailability(CancellationToken token) {
        var location = Input.location.lastData;
        try {
            var result = await geospatialManager.TryCheckVPSAvailabilityAsync(
                location.latitude, location.longitude);
            token.ThrowIfCancellationRequested();
            if (result.status.nativeStatusCode == (int)XrResultAndroid.GeospatialCoordinateInvalid) {
                // Invalid coordinates, try with another location.
            } else if (result.status.IsError()) {
                // Handle common OpenXR error: result.status.ToOpenXRStatus()
            }  else if (result.value == XRVPSAvailability.Available)  {
                // You may use this pose to attach geospatial anchors.
                var currentGeospatialPose = new XRGeospatialPose(location);
            }
        }
    }
  • In pratica, si tratta di un'alternativa se non vuoi controllare il supporto VPS tramite la mappa, ma devi uscire per controllare lo stato effettivo del GPS.

  • Inoltre, puoi convertire la posa tra la posa di Unity e la posa geospaziale tramite TryLocate.

    // Geospatial Pose -> Unity Pose
    var geospatialPose =
        new XRGeospatialPose(Input.location.lastData);
    if (geospatialManager.TryLocate(
            geospatialPose, out XRPoseResult result)) {
        if (result.IsPositionValid ||
            result.IsPositionTracked) {
            transform.position = result.Pose.position;
        }
        if (result.IsRotationValid ||
            result.IsRotationTracked) {
            transform.rotation = result.Pose.rotation;
        }
    }
    // Unity Pose -> Geospatial Pose
    Pose pose = new Pose(
        transform.position, transform.rotation);
    if (geospatialManager.TryLocate(
          pose, out XRGeospatialPoseResult result)) {
        if (result.IsPositionValid ||
            result.IsRotationValid) {
            // You may use for anchor attachment.
        }
    }
  • In base al risultato del controllo VPS o della conversione della posa, puoi quindi collegare l'ancoraggio spaziale a una determinata posa geospaziale o a un tipo di superficie noto, come un terreno o un tetto.

    async void PlaceAnchor(XRGeospatialPose pose) {
        try {
            Result<ARShareableAnchor> anchorResult;
            XRGeospatialSurfaceType typeToPlace = /* Choose your target type */;
            if (typeToPlace == XRGeospatialSurfaceType.Default) {
                anchorResult = geospatialManager.TryAttachGeospatialAnchor(pose);
            } else {
                pose.Altitude = 0;
                anchorResult = await geospatialManager.TryAttachSurfaceAnchorAsync(typeToPlace, pose);
            }
            if (anchorResult.status.IsSuccess()) {
                // ARShareableAnchorManager will track the anchor and update it.
            } else {
                // Handle OpenXR failures.
            }
        }
    }
  • E quando metti insieme tutto questo, puoi creare un'esperienza spaziale davvero magica con il mondo reale in primo piano.

  • In questo caso, inseriamo una freccia per indirizzare il pubblico verso il luogo di destinazione nel mondo reale.

  • Ok.

  • Quindi, l'SDK di Android XR non è l'unico pacchetto che abbiamo fornito agli sviluppatori Unity.

  • L'SDK di Android XR per Unity di Google ora include anche il framework di interazione di Android XR e il pacchetto audio di Android XR.

  • Siamo entusiasti di espandere l'SDK Android XR con un maggiore supporto delle funzionalità e l'inclusione di più entità spaziali.

Riepilogo e risorse

  • Bene, siamo quasi alla fine della sessione.

  • Puoi seguire la roadmap di Unity online per scoprire le novità in arrivo.

  • Non dimenticare che Unity 7, la nuova generazione di Unity, sarà disponibile all'inizio del prossimo anno.

  • Nel frattempo, puoi provare questi strumenti e creare un progetto utilizzando il modello di realtà mista o dare un'occhiata al progetto di esempio di AR Foundation sul nostro GitHub.

  • Inoltre, per scoprire di più su Spatial Entity e sul nostro supporto per i pacchetti Unity, puoi visitare la pagina sul sito per sviluppatori Android.

  • E infine, grazie a tutti.

  • Non vediamo l'ora di scoprire cosa riuscirai a creare con AR Foundation e l'entità spaziale su Android XR.

Codice

Snippet di codice

Snippet C# alle 10:34 in "Ancoraggi locali e persistenza"
async void CreateAnchorAsync(ARAnchorManager manager, Pose pose) {
    var result = await manager.TryAddAnchorAsync(pose);
    if (result.status.IsError()) {
        // handle error
        return;
    }
    var anchor = result.value;
}
Snippet C# al minuto 10:43 in "Ancoraggi locali e persistenza"
void RemoveAnchor(ARAnchorManager manager, ARAnchor anchor) {
    var result = manager.TryRemoveAnchor(anchor.trackableId);
    if (result.status.IsError()) {
        // handle error
        return;
    }
}

void DestroyAnchorComponent(ARAnchor anchor) {
    Destroy(anchor);
}
Snippet C# alle 11:00 in "Ancoraggi locali e persistenza"
async void SaveAnchorAsync(ARAnchorManager manager, ARAnchor anchor) {
    var result = await manager.TrySaveAnchorAsync(anchor);
    if (result.status.IsError()) {
        // handle error
        return;
    }

    // Save this value, then return it as an input parameter
    SerializableGuid guid = result.value;
}
Snippet C# al minuto 11:17 in "Ancoraggi locali e persistenza"
async void LoadAnchorAsync(ARAnchorManager manager, SerializableGuid guid) {
    var result = await manager.TryLoadAnchorAsync(guid);
    if (result.status.IsError()) {
        // handle error
        return;
    }

    ARAnchor anchor = result.value;
}
Snippet C# al minuto 16:45 in "Creazione con entità spaziali"
void Awake() {
    planeManager = GetComponent<ARPlaneManager>();
    planeManager.enabled = false;
    boundingBoxManager = GetComponent<ARBoundingBoxManager>();
    boundingBoxManager.enabled = false;
    permissionUtil = GetComponent<AndroidXRPermissionUtil>();
}

void OnEnable() {
    StartCoroutine(WaitForPermissions());
}
Snippet C# al minuto 16:58 in "Creazione con entità spaziali"
IEnumerator WaitForPermissions() {
    planeManager.enabled = false;
    boundingBoxManager.enabled = false;

    yield return new WaitUntil(() =>
        permissionUtil.AllPermissionGranted());

    // Enable after granted permissions and
    // restart subsystems.
    planeManager.enabled = true;
    boundingBoxManager.enabled = true;

    // Save permission status.
    permissionGranted = true;
}
Snippet C# alle 19:12 in "API Geospatial"
async Task TrySetAuthentication() {
    googleCloudFeature =
        OpenXRSettings.Instance
            .GetFeature<XRGoogleCloudFeature>();
    var result = await googleCloudFeature
        .TrySetAuthenticationAsync(
            strategy, credential);
    if (result.IsSuccess()) {
        // Ready to use for geospatial tracker.
    } else if (result.IsUnsupported())  {
        // Google Cloud feature is not supported
    } else if (result.IsKeylessError()) {
        // Confirm if keyless has been set up properly.
    } else {
        // Handling other common OpenXR errors.
    }
}
Snippet C# al minuto 20:24 in "API Geospatial"
void OnGeospatialStateChanged(XRGeospatialStateChangedEventArgs eventArgs) {
    bool isInitFailed = eventArgs.CurrState == XRGeospatialState.InitializationFailed;
    if (isInitFailed && XRGeospatialManager.InitializationResult.IsCloudAuthError()) {
        // Handle cloud authentication issues.
    } else if (isInitFailed) {
        // Check XRGeospatialManager.InitializationResult for other common OpenXR errors.
    } else {
        // Iterate runtime state change, and handle accordingly.
    }
}

private void OnEnable() {
    XRGeospatialManager.OnStateChanged += OnGeospatialStateChanged;
}
Snippet C# al minuto 20:38 in "API Geospatial"
async Task CheckVPSAvailability(CancellationToken token) {
    var location = Input.location.lastData;
    try {
        var result = await geospatialManager.TryCheckVPSAvailabilityAsync(
            location.latitude, location.longitude);
        token.ThrowIfCancellationRequested();
        if (result.status.nativeStatusCode == (int)XrResultAndroid.GeospatialCoordinateInvalid) {
            // Invalid coordinates, try with another location.
        } else if (result.status.IsError()) {
            // Handle common OpenXR error: result.status.ToOpenXRStatus()
        }  else if (result.value == XRVPSAvailability.Available)  {
            // You may use this pose to attach geospatial anchors.
            var currentGeospatialPose = new XRGeospatialPose(location);
        }
    }
}
Snippet C# al minuto 21:03 in "API Geospatial"
// Geospatial Pose -> Unity Pose
var geospatialPose =
    new XRGeospatialPose(Input.location.lastData);
if (geospatialManager.TryLocate(
        geospatialPose, out XRPoseResult result)) {
    if (result.IsPositionValid ||
        result.IsPositionTracked) {
        transform.position = result.Pose.position;
    }
    if (result.IsRotationValid ||
        result.IsRotationTracked) {
        transform.rotation = result.Pose.rotation;
    }
}
Snippet C# al minuto 21:03 in "API Geospatial"
// Unity Pose -> Geospatial Pose
Pose pose = new Pose(
    transform.position, transform.rotation);
if (geospatialManager.TryLocate(
      pose, out XRGeospatialPoseResult result)) {
    if (result.IsPositionValid ||
        result.IsRotationValid) {
        // You may use for anchor attachment.
    }
}
Snippet C# al minuto 21:11 in "API Geospatial"
async void PlaceAnchor(XRGeospatialPose pose) {
    try {
        Result<ARShareableAnchor> anchorResult;
        XRGeospatialSurfaceType typeToPlace = /* Choose your target type */;
        if (typeToPlace == XRGeospatialSurfaceType.Default) {
            anchorResult = geospatialManager.TryAttachGeospatialAnchor(pose);
        } else {
            pose.Altitude = 0;
            anchorResult = await geospatialManager.TryAttachSurfaceAnchorAsync(typeToPlace, pose);
        }
        if (anchorResult.status.IsSuccess()) {
            // ARShareableAnchorManager will track the anchor and update it.
        } else {
            // Handle OpenXR failures.
        }
    }
}