Faire en sorte que vos hologrammes restent en place, se déplacent avec vous ou, dans certains cas, se positionnent par rapport à d’autres hologrammes est une grande partie de la création d’applications Mixed Reality. Cet article vous guidera dans notre solution recommandée à l’aide de World Locking Tools, mais nous aborderons également la configuration manuelle des ancres spatiales dans vos projets Unity. Avant de passer à un code, il est important de comprendre comment Unity gère l’espace de coordination et les ancres dans son propre moteur.
Systèmes de coordonnées à l’échelle mondiale
Aujourd’hui, lors de l’écriture de jeux, d’applications de visualisation de données ou d’applications de réalité virtuelle, l’approche classique consiste à établir un système de coordonnées monde absolu auquel toutes les autres coordonnées peuvent être mappées de manière fiable. Dans cet environnement, vous pouvez toujours trouver une transformation stable qui définit une relation entre deux objets dans ce monde. Si vous ne déplacez pas ces objets, leurs transformations relatives restent toujours les mêmes. Ce type de système de coordonnées global est facile à obtenir lors du rendu d’un monde purement virtuel où vous connaissez toute la géométrie à l’avance. Aujourd’hui, les applications VR à l’échelle de la salle établissent généralement ce type de système de coordonnées absolu à l’échelle de la pièce avec son origine sur le sol.
En revanche, un appareil de réalité mixte non attaché tel que HoloLens a une compréhension dynamique du monde par capteur, qui ajuste en permanence sa connaissance de l’environnement de l’utilisateur au fil du temps à mesure qu’il marche plusieurs mètres à travers un étage entier d’un bâtiment. Dans une expérience à l’échelle mondiale, si vous placez tous vos hologrammes dans un système de coordonnées rigide naïve, ces hologrammes finissent par dériver au fil du temps, soit en fonction du monde, soit par rapport à l’autre.
Par exemple, le casque peut actuellement croire que deux emplacements dans le monde sont séparés de 4 mètres, puis affiner cette compréhension, en apprenant que les emplacements sont en fait à 3,9 mètres. Si ces hologrammes avaient été initialement placés à 4 mètres de distance dans un système de coordonnées rigide unique, l’un d’eux apparaît alors toujours à 0,1 mètre du monde réel.
Vous pouvez placer manuellement des ancres spatiales dans Unity pour maintenir la position d’un hologramme dans le monde physique lorsque l’utilisateur est mobile. Toutefois, cela sacrifie la cohérence de soi dans le monde virtuel. Différentes ancres se déplacent constamment les unes par rapport aux autres et se déplacent également dans l’espace de coordonnées global. Dans ce scénario, les tâches simples comme la disposition deviennent difficiles. La simulation physique peut également poser problème.
World Locking Tools (WLT) vous offre le meilleur des deux mondes, stabilisant un système de coordonnées rigide unique à l’aide d’un approvisionnement interne d’ancres spatiales réparties dans la scène virtuelle à mesure que l’utilisateur se déplace. WLT analyse les coordonnées de la caméra et ces ancres spatiales à chaque image. Au lieu de modifier les coordonnées de tout ce qui se trouve dans le monde pour compenser les corrections dans les coordonnées de la tête de l’utilisateur, WLT corrige simplement les coordonnées de la tête à la place.
Choisissez votre approche de verrouillage du monde
Si possible, utilisez World Locking Tools pour le positionnement des hologrammes.
World Locking Tools fournit un système de coordonnées stable qui réduit les incohérences visibles entre les marqueurs virtuels et réels. World Locking Tools verrouille la scène entière avec un pool partagé d’ancres, au lieu de verrouiller chaque groupe d’objets avec l’ancre individuelle du groupe.
World Locking Tools gère automatiquement la création et la gestion internes des ancres spatiales. Vous n’avez pas besoin d’interagir avec ARAnchorManager ou WorldAnchor pour garder vos hologrammes verrouillés dans le monde.
- Pour Unity 2019/2020 à l’aide d’OpenXR ou du plug-in Windows XR, utilisez ARAnchorManager.
- Pour les versions antérieures d’Unity ou les projets WSA, utilisez WorldAnchor.
Configurer le verrouillage mondial
Pour commencer à utiliser World Locking Tools, téléchargez l’outil de fonctionnalité Mixed Reality. Pour en savoir plus sur les principes de base, consultez la page de documentation principale de World Locking Tools pour obtenir des liens vers Vue d’ensemble, Démarrage rapide et d’autres rubriques utiles.
Configuration automatisée
Lorsque votre projet est prêt, exécutez l’utilitaire de configuration de scène à partir de Mixed Reality > World Locking Tools :
Importante
L’utilitaire Configurer la scène peut être réexécuté à tout moment. Par exemple, elle doit être réexécutée si la cible AR a été remplacée par le kit SDK XR hérité. Si la scène est déjà correctement configurée, l’exécution de l’utilitaire n’a aucun effet.
Visualiseurs
Au cours du développement précoce, l’ajout de visualiseurs peut être utile pour s’assurer que WLT est configuré et fonctionne correctement. Ils peuvent être supprimés pour les performances de production, ou si, pour une raison quelconque, ne sont plus nécessaires, à l’aide de l’utilitaire Supprimer les visualiseurs. Pour plus d’informations sur les visualiseurs, consultez la documentation outils.
Le plug-in OpenXR Mixed Reality fournit des fonctionnalités d’ancrage de base via une implémentation d’ARFoundation ARAnchorManager d’Unity. Pour découvrir les principes de base sur ARAnchors dans ARFoundation, consultez le manuel ARFoundation pour AR Anchor Manager.
Espace de noms :UnityEngine.XR.WSA
Type :WorldAnchor
Une technique clé consiste à créer une ancre spatiale pour verrouiller un cluster d’hologrammes précisément en place dans le monde physique, quelle que soit la distance parcourue par l’utilisateur, puis à retrouver ces hologrammes dans les sessions ultérieures.
Dans les versions antérieures d’Unity, vous créez une ancre spatiale en ajoutant le composant WorldAnchor Unity à un GameObject.
Ajouter une ancre mondiale
Pour ajouter une ancre mondiale, appelez AddComponent<WorldAnchor>() sur l’objet de jeu avec la transformation que vous souhaitez ancrer dans le monde réel.
WorldAnchor anchor = gameObject.AddComponent<WorldAnchor>();
Cet objet de jeu est maintenant ancré à son emplacement actuel dans le monde physique. Vous pouvez voir ses coordonnées de monde Unity s’ajuster légèrement au fil du temps pour garantir l’alignement physique. Consultez Charger une ancre mondiale pour trouver à nouveau cet emplacement ancré dans une session d’application future.
Supprimer une ancre mondiale
Si vous ne souhaitez plus que le GameObject verrouille à un emplacement du monde physique et que vous n’avez pas l’intention de le déplacer dans ce cadre, appelez Destroy le composant World Anchor.
Destroy(gameObject.GetComponent<WorldAnchor>());
Si vous souhaitez déplacer ce frame, appelez DestroyImmediate à la GameObject place.
DestroyImmediate(gameObject.GetComponent<WorldAnchor>());
Déplacer un GameObject ancré dans le monde
Vous ne pouvez pas déplacer tant GameObject qu’une ancre mondiale est dessus. Si vous devez déplacer ce GameObject cadre, vous devez :
-
DestroyImmediate composant World Anchor.
- Déplacez le
GameObject.
- Ajoutez un nouveau composant World Anchor à .
GameObject
DestroyImmediate(gameObject.GetComponent<WorldAnchor>());
gameObject.transform.position = new Vector3(0, 0, 2);
WorldAnchor anchor = gameObject.AddComponent<WorldAnchor>();
Gérer les modifications de locatabilité
Une ancre mondiale peut ne pas être locatable dans le monde physique à un moment donné. Unity ne met alors pas à jour la transformation de l’objet ancré. Cette situation peut également se produire pendant l’exécution d’une application. Si vous ne gérez pas la modification de la locatabilité, l’objet n’apparaît pas à l’emplacement physique correct dans le monde.
Pour être informé des modifications de locatabilité :
Abonnez-vous à l’événement OnTrackingChanged . L’événement OnTrackingChanged est appelé chaque fois que l’ancre spatiale sous-jacente change entre un état locatable ou non locatable.
anchor.OnTrackingChanged += Anchor_OnTrackingChanged;
Gérez l’événement.
private void Anchor_OnTrackingChanged(WorldAnchor self, bool located)
{
// This simply activates/deactivates this object and all children when tracking changes
self.gameObject.SetActiveRecursively(located);
}
Si les ancres sont localisées immédiatement, la isLocated propriété de l’ancre est définie sur true lorsque AddComponent<WorldAnchor>() retourne. Par conséquent, l’événement OnTrackingChanged n’est pas déclenché. Un modèle plus propre consiste à appeler le OnTrackingChanged gestionnaire avec l’état initial IsLocated après l’attachement d’une ancre.
Anchor_OnTrackingChanged(anchor, anchor.isLocated);
Verrouillage du monde persistant
Les ancres spatiales enregistrent les hologrammes dans un espace réel entre les sessions d’application. Une fois enregistrées dans le magasin d’ancres HoloLens, les ancres spatiales peuvent être trouvées et chargées dans différentes sessions et constituent une solution de secours idéale en l’absence de connectivité Internet.
Par défaut, World Locking Tools restaure le système de coordonnées d’Unity par rapport au monde physique entre les sessions sur les appareils qui prennent en charge la persistance des ancres spatiales locales. Pour qu’un hologramme apparaisse au même endroit dans le monde physique après avoir quitté et réexécuté l’application, il suffit à l’application de restaurer la même pose pour l’hologramme.
Si l’application a besoin d’un contrôle plus précis, vous pouvez désactiver l’enregistrement automatique et le chargement automatique dans l’inspecteur, et gérer la persistance à partir d’un script. Pour plus d’informations, consultez Conserver les systèmes de coordonnées spatiales.
World Locking Tools prend en charge la persistance des ancres locales uniquement sur les appareils HoloLens.
Une API appelée permet de XRAnchorStore conserver les ancres entre les sessions. est XRAnchorStore une représentation des ancres enregistrées sur un appareil. Vous pouvez conserver les ancres à partir de ARAnchors dans la scène Unity, charger des ancres à partir du stockage dans un nouveau ARAnchors, ou supprimer des ancres du stockage.
Remarque
Vous enregistrez et chargez ces ancres sur le même appareil.
Espaces de noms
Pour Unity 2020 et OpenXR :
using Microsoft.MixedReality.ARSubsystems.XRAnchorStore
ou Unity 2019/2020 + Plug-in Windows XR :
using UnityEngine.XR.WindowsMR.XRAnchorStore
Méthodes publiques
{
// A list of all persisted anchors, which can be loaded.
public IReadOnlyList<string> PersistedAnchorNames { get; }
// Clear all persisted anchors
public void Clear();
// Load a single persisted anchor by name. The ARAnchorManager will create this new anchor and report it in
// the ARAnchorManager.anchorsChanged event. The TrackableId returned here is the same TrackableId the
// ARAnchor will have when it is instantiated.
public TrackableId LoadAnchor(string name);
// Attempts to persist an existing ARAnchor with the given TrackableId to the local store. Returns true if
// the storage is successful, false otherwise.
public bool TryPersistAnchor(TrackableId id, string name);
// Removes a single persisted anchor from the anchor store. This will not affect any ARAnchors in the Unity
// scene, only the anchors in storage.
public void UnpersistAnchor(string name);
}
Obtenir une référence de magasin d’ancres
Pour charger le XRAnchorStore avec Unity 2020 et OpenXR, utilisez la méthode d’extension sur XRAnchorSubsystem, le sous-système d’un ARAnchorManager :
public static Task<XRAnchorStore> LoadAnchorStoreAsync(this XRAnchorSubsystem anchorSubsystem)
Pour charger le XRAnchorStore avec Unity 2019/2020 et le plug-in Windows XR, utilisez la méthode d’extension sur XRReferencePointSubsystem (Unity 2019) ou XRAnchorSubsystem (Unity 2020), le sous-système d’un ARReferencePointManager/ARAnchorManager :
// Unity 2019 + Windows XR Plugin
public static Task<XRAnchorStore> TryGetAnchorStoreAsync(this XRReferencePointSubsystem anchorSubsystem);
// Unity 2020 + Windows XR Plugin
public static Task<XRAnchorStore> TryGetAnchorStoreAsync(this XRAnchorSubsystem anchorSubsystem);
Charger un magasin d’ancres
Pour charger un magasin d’ancres dans Unity 2020 et OpenXR, accédez-y à partir d’un sous-système ARAnchorManager comme suit :
ARAnchorManager arAnchorManager = GetComponent<ARAnchorManager>();
XRAnchorStore anchorStore = await arAnchorManager.subsystem.LoadAnchorStoreAsync();
ou avec Unity 2019/2020 et le plug-in Windows XR :
// Unity 2019
ARReferencePointManager arReferencePointManager = GetComponent<ARReferencePointManager>();
XRAnchorStore anchorStore = await arReferencePointManager.subsystem.TryGetAnchorStoreAsync();
// Unity 2020
ARAnchorManager arAnchorManager = GetComponent<ARAnchorManager>();
XRAnchorStore anchorStore = await arAnchorManager.subsystem.TryGetAnchorStoreAsync();
Pour voir un exemple complet d’ancres persistantes/non persistantes, case activée le GameObject Anchors -> Anchors Sample et AnchorsSample.cs script dans la [Mixed Reality OpenXR Plugin Sample Scene]((https://github.com/microsoft/OpenXR-Unity-MixedReality-Samples) :
Pour la persistance des hologrammes dans les versions antérieures d’Unity ou les projets WSA, utilisez WorldAnchor.
Namespace :UnityEngine.XR.WSA.Persistence
Class :WorldAnchorStore
WorldAnchorStore crée des expériences holographiques où les hologrammes restent dans des positions spécifiques du monde réel sur les instances de l’application. Les utilisateurs peuvent épingler des hologrammes individuels où ils le souhaitent et les trouver plus tard au même endroit sur les sessions d’application.
le WorldAnchorStore vous permet de conserver l’emplacement des ancres mondiales entre les sessions. Pour conserver les hologrammes entre les sessions, effectuez une trace distincte des GameObjects hologrammes qui utilisent une ancre mondiale particulière. Vous pouvez créer une GameObject racine avec une ancre mondiale et ancrer des hologrammes enfants à l’aide d’un décalage de position locale.
Pour charger les hologrammes des sessions précédentes :
- Obtenez le
WorldAnchorStore.
- Chargez les données de l’application world anchor, ce qui vous donne l’ID de l’ancre mondiale.
- Chargez l’ancre mondiale par son ID.
Pour enregistrer des hologrammes pour les sessions futures :
- Obtenez le
WorldAnchorStore.
- Enregistrez une ancre mondiale en spécifiant un ID.
- Enregistrez les données d’application liées à l’ancre mondiale avec l’ID.
Obtenir le WorldAnchorStore
Conservez une référence à , WorldAnchorStoreafin de savoir quand il est prêt à effectuer une opération. Étant donné que cet appel est asynchrone, dès que l’application démarre, vous pouvez appeler :
WorldAnchorStore.GetAsync(StoreLoaded);
StoreLoaded est le gestionnaire à la fin du WorldAnchorStore chargement :
private void StoreLoaded(WorldAnchorStore store)
{
this.store = store;
}
Vous disposez maintenant d’une référence à , WorldAnchorStoreque vous pouvez utiliser pour enregistrer et charger des ancres de monde spécifiques.
Enregistrer une ancre mondiale
Pour enregistrer une ancre mondiale, nommez-la et passez-la dans le WorldAnchorStore que vous avez obtenu auparavant. Si vous essayez d’enregistrer deux ancres dans la même chaîne, store.Save retourne false. Supprimez l’enregistrement précédent avant d’en enregistrer un nouveau.
private void SaveGame()
{
// Save data about holograms that this world anchor positions
if (!this.savedRoot) // Only save the root once
{
this.savedRoot = this.store.Save("rootGameObject", anchor);
Assert(this.savedRoot);
}
}
Charger une ancre mondiale
Pour charger une ancre mondiale :
private void LoadGame()
{
// Saved data about holograms that this world anchor positions:
this.savedRoot = this.store.Load("rootGameObject", rootGameObject);
if (!this.savedRoot)
{
// Game root not saved. Re-place objects or start over.
}
}
Vous pouvez également utiliser store.Delete() pour supprimer une ancre que vous avez enregistrée précédemment et store.Clear() pour supprimer toutes les données précédemment enregistrées.
Énumérer les ancres existantes
Pour répertorier les ancres stockées, appelez GetAllIds.
string[] ids = this.store.GetAllIds();
for (int index = 0; index < ids.Length; index++)
{
Debug.Log(ids[index]);
}
Étapes suivantes
Partager un espace de coordonnées verrouillé :
En savoir plus sur le mappage spatial :
Retour aux points de contrôle de développement Unity :
Voir aussi