Android XR

Architecting Spatial Content on Android XR with Unity

Haut-parleurs

  • Levana Chen

    Ingénieur logiciel

  • Jennifer Stanton

    Ingénieur logiciel senior

À propos

À propos de l'intervention

Découvrez comment ancrer et conserver des expériences 3D dans le monde réel à l'aide d'Unity et d'Android XR. Cette session aborde le framework Spatial Entities, les ancres cloud et les API Geospatial, et montre comment créer des applications contextuelles qui mémorisent les emplacements physiques et synchronisent les données spatiales multi-utilisateurs entre les sessions.

Nous examinerons l'architecture des entités spatiales, et nous verrons comment ancrer des ressources numériques à des objets physiques, des surfaces et des emplacements géographiques. Vous repartirez avec des workflows Unity pratiques pour cartographier des espaces, conserver du contenu d'une session à l'autre et créer des expériences de RA/XR partagées et géolocalisées.

Résumé

  • AR Foundation fournit une API de script unifiée sur les plates-formes XR à l'aide d'extensions OpenXR. Il vous permet de représenter et d'interroger des éléments du monde réel, tels que des plans et des maillages.
  • Les ancres persistantes stabilisent le contenu numérique d'une session à l'autre et lors des redémarrages de l'appareil. Vous pouvez les conserver avec TrySaveAnchorAsync et les recharger à l'aide de GUID sérialisés.
  • Le framework Spatial Entities remplace les extensions traçables pour fournir une compatibilité multiplate-forme et de meilleures performances pour le suivi d'éléments tels que les cadres de délimitation et les marqueurs.
  • Les composants du gestionnaire doivent être désactivés tant que les autorisations Android XR ne sont pas accordées. Cela évite les échecs d'initialisation du sous-système causés par un accès restreint aux données d'environnement sensibles.
  • L'API Geospatial utilise les services ARCore de Google Cloud et le VPS pour positionner du contenu dans des lieux extérieurs réels.

Ressources

Gemini Notebook

Thèmes

  • android-xr
  • unité
  • ar-foundation
  • openxr
  • spatial-entities
  • Annonces ancrées
  • geospatial-api

Transcription

Introduction et présentation d'AR Foundation

  • Très bien.

  • Bienvenue à tous.

  • Voici "Concevoir du contenu spatial sur Android XR avec Unity".

  • Je m'appelle Jennifer Stanton.

  • Je travaille chez Unity en tant qu'ingénieur logiciel senior.

  • Je travaille dans l'équipe XR Features, plus précisément sur AR Foundation et les packages associés qui apportent la réalité augmentée et mixte à Unity.

  • Je m'appelle Levana Chen et je fais partie de l'équipe des moteurs de jeu XR de Google.

  • Nos équipes se sont concentrées sur la fourniture de plug-ins et de packages pour offrir des fonctionnalités XR améliorées et des intégrations fluides au moteur de jeu.

  • L'un des principaux défis que vous nous avez signalés est que la prise en charge de plusieurs plates-formes XR avec le même codebase demande beaucoup de travail.

  • AR Foundation est la couche d'API de réalité étendue de haut niveau d'Unity.

  • Vous pouvez cibler plusieurs plates-formes XR sans avoir à réécrire une grande partie du code ni à gérer plusieurs codebases. Vous disposez ainsi d'une seule API de script pour les fonctionnalités de RA sur n'importe quelle plate-forme.

  • Vous pouvez ainsi vous concentrer sur la création de votre application, de votre jeu ou de votre expérience, et Unity s'occupe des détails de la plate-forme pour vous.

  • Pour ce faire, AR Foundation utilise des extensions OpenXR.

  • Il s'agit d'un ensemble d'API ouvertes et conformes aux normes du secteur, définies par le Khronos Group.

  • OpenXR a également créé des entités spatiales.

  • Il s'agit d'un framework permettant au contenu numérique de représenter le monde physique et d'interagir avec lui.

  • Les entités spatiales fournissent un modèle unifié pour représenter des éléments du monde réel sous forme d'objets numériques.

  • Je suis ravi de vous présenter les dernières informations sur AR Foundation pour que vous puissiez commencer à créer des expériences pour la XR.

  • Ensuite, je vais passer en revue les fonctionnalités d'AR Foundation pour que votre contenu numérique puisse interagir avec le monde réel.

  • Ensuite, je vous expliquerai comment configurer le projet, y compris les packages et les autres dépendances, afin que vous puissiez l'implémenter dans vos projets.

  • Enfin, je terminerai en passant en revue certaines fonctionnalités propres à Android XR.

Principales fonctionnalités d'AR Foundation

  • AR Foundation représente le monde réel de manière numérique, par exemple, à l'aide de plans.

  • Il s'agit de surfaces planes de l'environnement physique, comme les sols, les murs, les plafonds, et même les tables et les canapés.

  • Les maillages sont des structures 3D représentant la géométrie du monde physique.

  • Nous disposons également de moyens d'interagir avec le monde réel, les lancers de rayons.

  • Ils déterminent l'endroit où un rayon croise le contenu numérique.

  • Imaginez un pointeur laser : vous obtenez des informations sur l'endroit où il pointe.

  • Nous avons également des ancres, qui aident à stabiliser et à relocaliser un point dans l'espace.

  • Je reviendrai plus en détail sur les ancres plus tard dans cette présentation.

  • Ces quatre éléments sont donc considérés comme des fonctionnalités d'AR Foundation.

  • Il existe également d'autres fonctionnalités qui ne sont pas mentionnées sur cette diapositive.

  • Les plans et les ancres, en particulier, sont considérés comme des éléments traçables, car ils étendent la classe ARTrackable, et leurs gestionnaires suivent les mises à jour de l'environnement d'exécution.

  • Passons maintenant aux plans.

  • Pour les plans, nous avons le composant ARPlane, qui permet d'identifier les surfaces planes en temps réel.

  • Ils ont des étiquettes sémantiques que vous pouvez interroger pour savoir si votre plan est un sol, une table, un mur, etc.

  • Les plans ont également des limites dynamiques. Ainsi, à mesure que l'utilisateur se déplace dans le monde réel et peut voir davantage de surfaces, les limites des plans s'étendent, fusionnent et s'affinent de manière dynamique en temps réel.

  • Nous pouvons également associer un Mesh Collider au plan pour gérer la physique.

  • Voici un exemple de détection de plan.

  • Il s'agit de la scène de lancer de rayons des exemples AR Foundation exécutée sur un appareil Android XR.

  • Elle détecte les polygones 2D dynamiques en temps réel.

  • Vous pouvez créer une application dotée de cette fonctionnalité en suivant notre guide de configuration de projet ou en utilisant l'un de nos exemples ou modèles.

  • Ensuite, nous avons les maillages.

  • Les maillages sont une fonctionnalité de RA qui fournit des maillages 3D de l'environnement.

  • Nous pouvons associer un collisionneur de maillage à ces maillages générés, ce qui permet à votre contenu numérique d'interagir avec des objets du monde réel.

  • Les maillages permettent une occlusion convaincante des objets.

  • Un objet virtuel peut donc sembler se trouver derrière un objet physique.

  • Si votre objet numérique peut se déplacer dans l'espace, vous pouvez utiliser la même géométrie pour trouver un chemin qui évite les objets du monde réel.

  • Passons maintenant au lancer de rayons.

  • Le lancer de rayons projette des rayons virtuels dans votre scène 3D pour rechercher des intersections sans que vous ayez à vous soucier des calculs mathématiques complexes.

  • Un rayon projeté peut potentiellement croiser plusieurs objets 3D dans votre environnement.

  • Vous pouvez configurer le lancer de rayon pour qu'il ne touche que certains types de contenus numériques.

  • Par exemple, vous pouvez le configurer pour qu'il ne touche pas les plans et qu'il n'intersecte qu'avec les maillages.

Configuration des packages et des dépendances

  • Examinons maintenant les packages pertinents.

  • Ces packages fonctionnent tous ensemble pour communiquer entre eux et créer une expérience XR complète.

  • Comme indiqué, AR Foundation gère des fonctionnalités telles que les plans et les ancres.

  • Le plug-in OpenXR gère les API natives sur différentes plates-formes XR. Vous devez donc utiliser ce package si votre appareil utilise OpenXR.

  • Le plug-in OpenXR peut éventuellement être associé au package OpenXR Spatial Entities pour accéder spécifiquement aux extensions Spatial Entities. Nous y reviendrons plus tard.

  • Si vous savez que vous allez cibler spécifiquement des appareils Android XR, comme les casques XR et les lunettes XR filaires, vous aurez besoin du package Unity OpenXR Android XR.

  • Comme tout cela suit le modèle de plug-in, l'impact sur votre code devrait rester minime.

  • Certaines fonctionnalités ne sont pas disponibles dans tous les packages AR Foundation.

  • Par exemple, si vous regardez ce tableau, le maillage n'est pas disponible actuellement dans le package Unity OpenXR Spatial Entities.

  • La gestion des plug-ins XR vous permet de gérer les fonctionnalités OpenXR sélectionnées dans votre projet.

  • Si vous êtes dans l'éditeur Unity, accédez à Edit > Project Settings (Modifier > Paramètres du projet). XR Plug-in Management (Gestion des plug-ins XR) se trouve dans la barre latérale de gauche.

  • Vous y trouverez les fonctionnalités et groupes de fonctionnalités OpenXR, ce qui vous permettra de sélectionner et de désélectionner les fonctionnalités et groupes de fonctionnalités que vous souhaitez inclure dans votre build.

  • Par exemple, dans cette capture d'écran, nous voyons tous ceux qui sont fournis avec le package Android XR OpenXR.

  • Vous pouvez ensuite les combiner avec des entités spatiales, par exemple, si vous le souhaitez.

  • Voici la fenêtre du gestionnaire de paquets.

  • J'ai mis en évidence certains des packages que vous pourriez voir dans une configuration de projet XR classique.

  • Comme vous pouvez le voir, nous avons AR Foundation, qui a été mentionné.

  • Nous avons également le plug-in OpenXR.

  • Nous avons le package Android XR.

  • J'en ai également mis en évidence d'autres provenant d'autres plates-formes, car vous pouvez tout à fait créer un projet qui se compile sur plusieurs plates-formes.

  • En bas à droite, vous trouverez d'autres packages.

  • Composition Layers, qui fonctionne avec les appareils OpenXR ; Core Utils, très utile pour tout ce qui concerne la XR ; et XR Hands et XR Interaction Toolkit pour obtenir vos entrées, ce qui est essentiel.

  • Ensuite, nous avons la validation du projet.

  • Encore une fois, cela fait partie de XR Plug-in Management.

  • La validation du projet peut détecter les caractéristiques en double, ainsi que d'autres problèmes dans votre projet que vous devez corriger pour l'exécuter.

  • Mais dans cette capture d'écran, j'ai mis en évidence les caractéristiques en double.

  • En gros, cela signifie que deux fonctionnalités identiques, comme les ancres, les plans et les lancers de rayons,

  • L'utilisateur a choisi d'inclure des doublons de ces fonctionnalités provenant de plusieurs packages, et il est simplement invité à sélectionner l'un ou l'autre.

Ancrages locaux et persistance

  • Cela nous amène aux ancres locales et à la persistance.

  • Les ancres garantissent que le contenu numérique reste aux emplacements souhaités dans l'environnement, quelles que soient les modifications apportées à l'état de suivi de la session de RA.

  • Les plates-formes de RA mettent automatiquement à jour les positions des ancres au fil du temps pour s'assurer qu'elles restent à un emplacement cohérent. Les ancres sont le meilleur moyen de s'assurer que votre contenu reste en place si vous vous éloignez de votre ancre, puis que vous revenez vers elle.

  • Et que se passe-t-il lorsque l'utilisateur ferme l'application, la redémarre plus tard et y revient dans une session distincte ?

  • Les ancres persistantes vous permettent d'enregistrer des ancres dans une session de RA, puis de les charger dans les sessions suivantes.

  • Ils survivent aux cycles de vie des applications et aux redémarrages de l'appareil.

  • Voici notre exemple d'ancres persistantes dans le projet d'exemples AR Foundation.

  • L'exemple de scène comporte un menu qui contient toutes les fonctionnalités compatibles avec cette plate-forme, telles que l'enregistrement et le chargement des ancres.

  • Cela nous amène au cycle de vie des ancres persistantes.

  • Vous devez d'abord créer une ancre localement. Elle n'est donc pas encore enregistrée, ni dans un espace de stockage persistant, ni ailleurs. Il s'agit simplement d'une ancre locale.

  • Vous les conserveriez ensuite dans l'espace de stockage.

  • Vous pouvez ensuite redémarrer l'application, puis la charger à partir de l'espace de stockage.

  • Certaines plates-formes, dont Android XR, permettent également d'effacer ou de supprimer la persistance des ancres.

  • Le fournisseur d'entités spatiales permet de charger automatiquement toutes les ancres enregistrées, ce qui vous évite d'avoir à demander manuellement chaque ancre par son ID.

  • Dans les paramètres de gestion du plug-in XR, vous pouvez sélectionner l'option "Automatically Load Saved Anchors" (Charger automatiquement les ancres enregistrées) dans la fonctionnalité "Spatial Entities: Anchors" (Entités spatiales : ancres).

  • Et l'enregistrement d'une ancre ne nécessite que quelques lignes de code.

  • Tout d'abord, nous commençons dans l'éditeur Unity et nous nous assurons que votre scène est prête en ajoutant le composant AR Anchor Manager à votre objet de jeu XR Origin.

  • Le gestionnaire maintient la scène à jour avec les ancres suivies de l'environnement d'exécution.

  • Cela nous amène au code.

  • Pour ajouter une ancre, il vous suffit d'appeler TryAddAnchorAsync et de transmettre la position où vous souhaitez placer votre ancre.

    async void CreateAnchorAsync(ARAnchorManager manager, Pose pose) {
        var result = await manager.TryAddAnchorAsync(pose);
        if (result.status.IsError()) {
            // handle error
            return;
        }
        var anchor = result.value;
    }
  • Ensuite, nous avons la suppression des ancres.

    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);
    }
  • De même, il ne s'agit que d'une seule ligne de code.

  • Vous appelez TryRemoveAnchor et transmettez l'ID de l'élément traçable de l'ancre.

  • Lors de la création de l'ancre, un ID de suivi lui a déjà été attribué.

  • Ensuite, nous avons 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;
    }
  • Vous transmettez une ancre de RA en entrée.

  • Cette fonction renvoie un SerializableGuid qui identifie l'ancre dans l'espace de stockage persistant.

  • Vous pourrez l'utiliser ultérieurement lors du chargement de l'ancre.

  • Cela nous amène au chargement des ancres.

    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 fonction à appeler ici est TryLoadAnchorAsync, et vous transmettez le GUID sérialisé précédemment.

  • Elle renvoie une ancre de RA.

  • Et c'est à peu près tout.

  • Ces fonctions vous permettent de gérer facilement les ancres locales et persistantes.

  • Le suivi des ancres est donc une tâche assez coûteuse sur la plupart des plates-formes de RA.

  • Lorsque vous utilisez des ancres, tenez compte des bonnes pratiques suivantes : évitez de créer plusieurs ancres très proches les unes des autres, déterminez si vous pouvez utiliser une ancre à proximité au lieu d'en créer une autre, supprimez les ancres lorsque vous ne les utilisez plus et, enfin, si vous activez une autre fonctionnalité de RA pour vous aider à calculer la pose souhaitée pour une ancre, déterminez si vous pouvez désactiver cette fonctionnalité une fois l'ancre créée.

  • Je laisse maintenant la parole à Levana.

SDK Android XR pour Unity

  • Merci, Jennifer.

  • Je vais maintenant vous présenter la contribution de Google au parcours Android XR dans Unity.

  • En plus des plug-ins Unity OpenXR présentés par Jennifer, Google fournit le SDK Android XR pour Unity, qui offre des fonctionnalités supplémentaires disponibles sur la plate-forme Android XR.

  • Ce SDK contient de nombreuses fonctionnalités et packages. Dans cette présentation, nous allons nous concentrer sur le package d'extension Android XR pour Unity.

  • Ainsi, comme OpenXR Android XR et les entités spatiales OpenXR, le package d'extension Android XR pour Unity est en fait un fournisseur OpenXR.

  • L'architecture de ce package ressemble à ceci, et ils peuvent fonctionner en parallèle ou indépendamment.

  • Comme tous les autres fournisseurs OpenXR, le package de Google est donc basé directement sur l'interface OpenXR standard.

  • Voici une comparaison de plusieurs fonctionnalités entre les différents fournisseurs.

  • Vous pourrez ainsi décider quand et pourquoi choisir l'un plutôt que l'autre.

  • Vous vous demandez peut-être ce que sont les marqueurs d'entité traçable et spatiale indiqués dans ce tableau.

  • Voici une remarque : pour ceux qui ont déjà créé des applications et des expériences sur Android XR, nous avons fourni ces fonctionnalités via les extensions de suivi, qui ne fonctionnent que sur Android XR.

  • Ensuite, comme l'a mentionné Jennifer, nous avons travaillé en tant que groupe ouvert OpenXR, puis nous avons publié l'extension Spatial Entities sur la droite et fourni une expérience cohérente et multiplate-forme.

  • Nous abandonnons actuellement l'extension Trackable au profit du framework Spatial Entities.

  • Non seulement cette dernière est beaucoup plus performante, mais elle est également compatible avec plusieurs plates-formes.

Créer avec des entités spatiales

  • Examinons ensuite de plus près les entités spatiales.

  • En plus des plans, du lancer de rayons et des ancres mentionnés par Jennifer, cette fonctionnalité est également compatible avec les fournisseurs d'entités spatiales, tels que les marqueurs, qui peuvent détecter et décoder les codes-barres 2D standards et suivre leur position dans l'espace 3D, et l'image qui reconnaîtra les graphiques 2D connus et les suivra dans l'espace 3D.

  • Ensuite, le cadre de délimitation, qui identifiera l'objet physique, comme un clavier, un ordinateur portable ou une souris, et suivra son cadre de délimitation en pose 3D.

  • Dans l'exemple suivant, nous allons configurer la fonctionnalité de cadre de délimitation fournie par le package d'extensions de Google.

  • Cette vue est pratiquement la même pour toutes les fonctionnalités OpenXR.

  • Il vous suffit donc de passer à la plate-forme Android XR, d'activer le fournisseur OpenXR et de sélectionner la fonctionnalité OpenXR que vous souhaitez utiliser pour la compilation (par exemple, la fonctionnalité de cadre de délimitation d'entité spatiale présentée ici), puis de corriger les problèmes de validation du projet.

  • Il vous aidera à trouver toutes les dépendances requises par une fonctionnalité donnée, puis à résoudre les conflits causés par plusieurs fonctionnalités contribuant au même sous-système.

  • La plupart du temps, il vous suffit de choisir une seule fonctionnalité si vous souhaitez utiliser, par exemple, une ancre, un plan ou un cadre de délimitation ici.

  • Enfin, vous pouvez simplement créer l'exemple de scène ou votre scène de test.

  • Pour accéder à l'objet traçable au moment de l'exécution, il vous suffit d'ajouter le composant AR Bounding Box Manager. Il s'agit d'un composant similaire à AR Anchor Manager. Vous pouvez ensuite utiliser l'interface AR Foundation pour y accéder.

  • Vous pouvez également importer l'exemple d'entité spatiale fourni par notre package d'extension en tant que modèle de départ.

  • Voici la principale différence lorsque vous utilisez la fonctionnalité AR Foundation sur Android XR.

  • Pour mieux comprendre l'environnement de l'utilisateur, votre application doit généralement accéder aux données sensibles de cet environnement.

  • Pour protéger l'utilisateur, Android XR restreint l'accès aux données du système derrière les autorisations.

  • Vous connaissez peut-être déjà ce concept, comme l'appel d'autorisation Android normal, par exemple l'accès à l'appareil photo ou à la position, etc.

  • La bonne pratique consiste à désactiver le composant du gestionnaire au démarrage, soit depuis l'éditeur (comme vous pouvez le voir à droite), soit depuis un script, comme l'événement Awake.

    void Awake() {
        planeManager = GetComponent<ARPlaneManager>();
        planeManager.enabled = false;
        boundingBoxManager = GetComponent<ARBoundingBoxManager>();
        boundingBoxManager.enabled = false;
        permissionUtil = GetComponent<AndroidXRPermissionUtil>();
    }
    
    void OnEnable() {
        StartCoroutine(WaitForPermissions());
    }
  • Une fois que vous avez accordé toutes les autorisations requises, vous pouvez activer le gestionnaire à partir du script, comme le fait l'assistant WaitForPermissions ici.

    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;
    }
  • Vous éviterez ainsi un échec d'initialisation du sous-système dû à des autorisations insuffisantes.

  • Et voici une fonctionnalité spéciale.

  • Comme Jennifer l'a expliqué, pour étendre les fonctionnalités des ancres sur Android XR, notre package fournit également une nouvelle fonctionnalité appelée "ancres partageables".

  • Cette fonctionnalité reproduit ce que la fonctionnalité d'ancrage d'AR Foundation accepte actuellement et propose également des fonctionnalités supplémentaires, telles que les ancres géospatiales.

  • Comme vous pouvez l'imaginer, l'ancrage est le véritable pont qui relie le monde virtuel au monde physique.

  • Jennifer nous a expliqué comment les créer, les enregistrer et les charger, mais tout cela s'est passé dans un espace local, comme le salon de votre utilisateur.

  • Et en ce qui concerne le reste du monde ?

  • Et comment pourrions-nous la partager entre nous ?

API Geospatial

  • C'est là que l'API Geospatial entre en jeu.

  • Elle vous permet de créer une ancre géospatiale basée sur un lieu réel, comme votre librairie préférée ou un point de rendez-vous dans un grand parc.

  • L'API Geospatial peut donc vous fournir un outil de suivi géospatial précis grâce au VPS (Virtual Positioning System), qui fonctionne comme un GPS, mais utilise les données Street View extérieures pour fournir des résultats de suivi beaucoup plus précis.

  • Certains d'entre vous connaissent peut-être déjà cette vue s'ils ont déjà utilisé la fonctionnalité géospatiale d'ARCore.

  • Pour accéder à l'API Geospatial sur Android XR, nous devons d'abord nous connecter au backend hébergé sur Google Cloud Platform.

  • Comme le backend géospatial est en fait optimisé par le service ARCore sur Google Cloud, vous pouvez suivre exactement la même procédure pour configurer votre projet Google Cloud avec l'accès à l'API ARCore.

  • Tout cela permettra ensuite d'utiliser la fonctionnalité Google Cloud d'Android XR fournie par notre package d'extension.

  • Une fois que vous avez activé l'API Geospatial et récupéré la clé API du projet Google Cloud, vous pouvez activer cette fonctionnalité et configurer l'authentification via le menu des paramètres OpenXR, comme indiqué ici. Vous pouvez également la configurer manuellement via l'API de script appelée 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.
        }
    }
  • Notez que la plate-forme Android XR n'est actuellement compatible qu'avec l'authentification par clé API, mais que d'autres types d'identifiants seront pris en charge à l'avenir.

  • Une fois authentifié, vous pouvez utiliser un gestionnaire géospatial pour accéder aux fonctionnalités géospatiales.

  • Nous vous recommandons vivement de vérifier la couverture du VPS sur Google Maps avant l'intégration.

  • Par conséquent, vous devez également disposer d'un accès réseau lorsque vous utilisez la fonctionnalité.

  • Le gestionnaire XR Geospatial fonctionne de la même manière que le composant de session RA fourni par AR Foundation.

  • Il est donc fourni avec une propriété d'état statique pour indiquer la compatibilité du système et l'état de suivi du traceur géospatial.

  • Vous pouvez enregistrer un événement de changement d'état à l'aide d'un rappel comme celui-ci.

    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;
    }
  • Une fois que l'état géospatial est "en cours d'exécution", vous pouvez utiliser cette instance de gestionnaire pour toutes les fonctionnalités suivantes.

  • Tout d'abord, pour vérifier la disponibilité du VPS avec la position GPS donnée, nous utilisons l'API de localisation d'Unity pour obtenir la valeur GPS, puis nous vérifions la disponibilité du 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);
            }
        }
    }
  • Il s'agit donc d'une alternative si vous ne souhaitez pas vérifier la compatibilité avec le VPS via la carte, mais vous devez sortir pour vérifier l'état réel du GPS.

  • Vous pouvez également convertir la pose entre la pose Unity et la pose géospatiale à l'aide de 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.
        }
    }
  • En utilisant le résultat de la vérification du VPS ou de la conversion de la pose, vous pouvez ensuite associer l'ancre spatiale à une pose géospatiale donnée ou à un type de surface connu, comme un terrain ou un toit.

    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.
            }
        }
    }
  • En combinant tous ces éléments, vous pouvez créer une expérience spatiale véritablement magique, avec le monde réel au premier plan.

  • Ici, nous plaçons une flèche pour guider notre audience vers l'endroit ciblé dans le monde réel.

  • OK.

  • Le SDK Android XR n'est pas le seul package que nous fournissons aux développeurs Unity.

  • Le SDK Android XR de Google pour Unity inclut désormais le framework d'interaction Android XR et le package audio Android XR.

  • Nous sommes également ravis d'étendre le SDK Android XR en ajoutant la prise en charge de fonctionnalités et d'entités spatiales supplémentaires.

Conclusion et ressources

  • Voilà, nous arrivons à la fin de la session.

  • Vous pouvez suivre la feuille de route d'Unity en ligne pour découvrir les nouveautés à venir.

  • N'oubliez pas que Unity 7, la nouvelle génération d'Unity, sera disponible au début de l'année prochaine.

  • En attendant, vous pouvez essayer ces outils et créer un projet à l'aide du modèle de réalité mixte ou consulter l'exemple de projet AR Foundation sur notre page GitHub.

  • Pour en savoir plus sur Spatial Entity et la compatibilité de notre package Unity, consultez la page sur le site des développeurs Android.

  • Merci à tous.

  • Nous avons hâte de découvrir ce que vous allez créer avec AR Foundation et l'entité spatiale sur Android XR.

Code

Extraits de code

Extrait de code C# à 10:34 dans "Ancrages locaux et persistance"
async void CreateAnchorAsync(ARAnchorManager manager, Pose pose) {
    var result = await manager.TryAddAnchorAsync(pose);
    if (result.status.IsError()) {
        // handle error
        return;
    }
    var anchor = result.value;
}
Extrait de code C# à 10:43 dans "Ancrages locaux et persistance"
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);
}
Extrait C# à 11:00 dans "Ancrages locaux et persistance"
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;
}
Extrait C# à 11:17 dans "Ancrages locaux et persistance"
async void LoadAnchorAsync(ARAnchorManager manager, SerializableGuid guid) {
    var result = await manager.TryLoadAnchorAsync(guid);
    if (result.status.IsError()) {
        // handle error
        return;
    }

    ARAnchor anchor = result.value;
}
Extrait de code C# à 16:45 dans "Créer avec des entités spatiales"
void Awake() {
    planeManager = GetComponent<ARPlaneManager>();
    planeManager.enabled = false;
    boundingBoxManager = GetComponent<ARBoundingBoxManager>();
    boundingBoxManager.enabled = false;
    permissionUtil = GetComponent<AndroidXRPermissionUtil>();
}

void OnEnable() {
    StartCoroutine(WaitForPermissions());
}
Extrait C# à 16:58 dans "Créer avec des entités spatiales"
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;
}
Extrait de code C# à 19:12 dans "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.
    }
}
Extrait de code C# à 20:24 dans "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;
}
Extrait de code C# à 20:38 dans "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);
        }
    }
}
Extrait de code C# à 21:03 dans "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;
    }
}
Extrait de code C# à 21:03 dans "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.
    }
}
Extrait de code C# à 21:11 dans "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.
        }
    }
}