Godot sur XREAL AURA : Guide pratique du développement spatial natif
En bref
Découvrez comment développer en spatial natif sur XREAL AURA avec Godot : éditeur intégré, conteneurs OpenXR, pièges d'ancrage et bonnes pratiques.
Votre pipeline de build XR implique aujourd'hui de vous connecter à un bureau, d'exporter un APK, de le sideloader via ADB, d'enfiler le casque, de découvrir une coquille, et de recommencer. XREAL AURA élimine complètement cette boucle, et Godot fait partie des titres de lancement avec un éditeur complet qui tourne directement sur les lunettes. Cela change ce que « itérer » signifie pour le développement spatial.
Ce guide détaille le workflow réel : faire tourner l'éditeur sur AURA, structurer une scène spatiale avec les conteneurs spatiaux OpenXR, gérer le modèle passthrough/see-through qui distingue les lunettes optiques des casques VR, et les pièges qui vous mordront lors de votre première exportation.
Pourquoi le see-through optique change vos hypothèses de conception
XREAL AURA est le premier appareil optique see-through sur Android XR. Cette seule phrase brise les hypothèses intégrées dans la plupart des tutoriels Godot XR.
Dans un casque VR, la caméra du casque rend tout. L'utilisateur voit votre environnement et rien d'autre. Sur des lunettes optiques see-through, l'utilisateur voit à travers les verres le monde réel, et votre contenu rendu est composé par-dessus. Ce n'est pas la même chose que le passthrough vidéo d'un Quest — le passthrough vidéo capture la réalité avec des caméras et la réaffiche, ce qui introduit latence et perte de lumière. Le see-through optique a une latence de composition nulle pour le monde réel.
Conséquences pratiques pour votre budget de rendu :
- Vous ne pouvez pas assombrir le monde réel. Le noir sur un écran transparent est transparent. Vous n'avez aucun arrière-plan opaque, donc une UI qui repose sur le contraste avec des panneaux sombres échouera dans une pièce lumineuse.
- Le contenu à l'aspect additif gagne. Le contenu émissif lumineux se lit bien ; le contenu sombre et désaturé disparaît. Concevez votre palette avec 2 à 3 fois la luminance que vous utiliseriez en VR.
- Le champ de vision est plus étroit qu'en VR. Le contenu placé à des angles extrêmes sort de la zone d'affichage. Gardez les cibles d'interaction principales à environ ±30 degrés du centre avant.
Si vous avez déjà livré de la VR, prévoyez de réajuster chaque matériau et chaque panneau d'UI. Comptez une journée complète par scène.
Installer l'éditeur Godot sur les lunettes
L'éditeur est distribué sur Google Play, pas sous forme d'APK sideloadé. C'est important, car cela signifie que vous pouvez le mettre à jour comme n'importe quelle autre application.
La séquence d'installation :
- Installez l'éditeur Godot sur XREAL AURA depuis le Play Store.
- Installez l'application compagnon d'environnement de build Gradle. Elle fournit la toolchain d'export Android, vous n'avez donc pas à construire un JDK et un SDK Android à partir de zéro sur l'appareil.
- Connectez-vous avec une identité de développeur Android si vous prévoyez de signer et publier des builds depuis l'appareil.
- Lancez l'éditeur — il s'ouvre dans un espace de travail spatial multi-fenêtres plutôt que dans une seule fenêtre plate.
Ce quatrième point est le plus intéressant. L'éditeur offre l'ensemble des fonctionnalités de type bureau, mais disposées en fenêtres flottantes dans l'espace. Vous pouvez garder l'arbre de scène dans un volume et le viewport 2D dans un autre.
Ce que le workflow sur l'appareil vous apporte réellement
La réponse honnête : une itération rapide sur le ressenti, plus lente sur les assets.
Modifier les shaders, ajuster les transformations de nœuds et tester les mappings d'entrée sur l'appareil ciblé élimine tout le cycle export-test. Ce cycle prend généralement 3 à 8 minutes une fois que l'on compte le temps de build, le transfert et le relancement. Dix itérations, c'est une heure perdue.
Ce qu'il n'aide pas à faire : importer de grands atlas de textures, lancer de longs bakes de lightmaps, ou tout ce qui est intensif en CPU. Faites cela sur une station de travail. La répartition réaliste est la création d'assets sur le bureau, l'assemblage et le réglage de scène sur les lunettes.
Créer du contenu spatial avec les conteneurs spatiaux OpenXR
Le support Android XR de Godot inclut les conteneurs spatiaux OpenXR — des volumes gérés par le système où votre application place du contenu spatial. L'analogie de la plateforme est assez juste : les applications traditionnelles dessinent du contenu 2D dans des fenêtres sur un bureau ; les applications spatiales dessinent du contenu 3D dans des conteneurs dans une pièce.
Il y a deux types de conteneurs à comprendre avant d'écrire du code :
| Type de conteneur | Idéal pour | Compromis |
|---|---|---|
| Volume | Objets 3D avec profondeur réelle, placement verrouillé au monde | Le système peut limiter les bornes du volume |
| Panneau | Surfaces d'UI, texte, jeux 2D | Rendu sur un plan fixe ; les indices de profondeur sont plats |
L'erreur que la plupart des développeurs commettent est de choisir le volume pour l'UI. Le texte dans un conteneur volume est mis à l'échelle et déplacé par le système de manières que vous ne pouvez pas entièrement prédire, et votre widget radar soigneusement positionné dérive. Mettez l'UI dans un conteneur panneau et laissez le système gérer le placement.
Travailler avec l'API des conteneurs spatiaux
Godot expose les conteneurs spatiaux via des classes d'extension OpenXR. Les noms de classes exacts dépendent de votre version de Godot, alors vérifiez la liste des fonctionnalités du moteur pour les bindings actuels des conteneurs spatiaux avant d'écrire du code de production. Le schéma ci-dessous reflète la structure typique du contenu XR basé sur des conteneurs.
extends Node3D
signal container_created(handle: int)
# Spatial container setup for Android XR.
# Class names are version-dependent; verify against the
# OpenXR extension bindings shipped with your Godot build.
var volume_container: SpatialContainer
var panel_container: SpatialContainer
func _ready() -> void:
var xr_interface: XRInterface = XRServer.find_interface("OpenXR")
if xr_interface == null or not xr_interface.is_initialized():
push_error("OpenXR interface unavailable on this device.")
return
# Volume container for the 3D board.
volume_container = SpatialContainer.new()
volume_container.container_type = SpatialContainer.TYPE_VOLUME
volume_container.extent = Vector3(0.6, 0.4, 0.6) # 60cm x 40cm x 60cm
if volume_container.request_container() != OK:
push_error("Volume container request failed.")
return
# Panel container for the HUD.
panel_container = SpatialContainer.new()
panel_container.container_type = SpatialContainer.TYPE_PANEL
panel_container.extent = Vector3(0.4, 0.4, 0.02)
panel_container.request_container()
add_child(volume_container)
add_child(panel_container)
container_created.emit(volume_container.get_container_handle())
func _process(_delta: float) -> void:
# Containers can be rejected or resized by the system.
if volume_container and not volume_container.is_active():
_handle_container_loss()
func _handle_container_loss() -> void:
push_warning("Volume container lost - repositioning.")
# Never assume the container survives; re-request on loss.
volume_container.request_container()
L'écueil que presque tout le monde rencontre : la dérive d'ancrage
Voici le problème spécifique, et c'est celui qui vous coûtera le plus de temps de débogage.
Vous placez un plateau 3D dans un conteneur volume. Vous appuyez sur Play. Tout semble correct. Vous retirez les lunettes, les remettez deux minutes plus tard, et le plateau est maintenant à un demi-mètre sur la gauche et tourné de 20 degrés.
Pourquoi ? Parce que vous avez ancré votre contenu à l'origine du monde plutôt qu'au conteneur. L'origine du monde sur un appareil spatial n'est pas un endroit stable — elle est définie par rapport à la pose de début de session. Quand la session se ré-ancre, l'origine du monde bouge.
Le correctif est de garder chaque élément de votre scène comme enfant de la transformation du conteneur, et de ne jamais lire ou écrire la position globale pour le contenu spatial :
# WRONG: assumes world origin is stable
func place_piece(piece: Node3D, board_pos: Vector3) -> void:
piece.global_position = board_pos
# RIGHT: position relative to the container transform
func place_piece(piece: Node3D, board_pos: Vector3) -> void:
piece.position = board_pos # local to container
piece.rotation = Vector3.ZERO
Faites un grep dans votre projet pour .global_position et .global_transform avant de livrer. Chaque occurrence dans le contenu spatial est un bug de dérive potentiel. Cette classe de bug apparaît aussi en 3D classique et en multijoueur — les erreurs d'ancrage et de propriété sur une transformation répliquée produisent exactement le même symptôme « objet téléporté pour certains clients », c'est pourquoi traiter les transformations comme locales au conteneur plutôt qu'absolues est une habitude à conserver dans tout projet Godot en réseau.
Vérifier le correctif
Pour confirmer que l'ancrage est correct :
- Lancez votre scène et notez la position du plateau.
- Retirez l'appareil, attendez 60 secondes, rentrez dans l'application.
- Le plateau doit apparaître au même emplacement physique par rapport à la pièce, pas au même décalage par rapport à l'endroit où vous vous tenez.
- Répétez avec l'appareil dans une orientation différente — assis, puis debout.
S'il dérive, votre arbre de contenu contient encore des références absolues. S'il saute mais reste cohérent après le saut, le conteneur est repositionné et votre contenu le suit correctement — c'est un comportement attendu, pas un bug.
Gérer l'identité du joueur et l'état persistant
Les applications spatiales sur Android XR sont des applications Android. Elles se suspendent, elles reprennent, l'utilisateur peut avoir plusieurs identités connectées sur l'appareil, et vos données de sauvegarde vivent dans le même écosystème de comptes que tout le reste.
Le mode de défaillance est subtil : un joueur joue en spatial sur les lunettes, puis ouvre le même jeu sur son téléphone. Si votre état de sauvegarde est local à l'appareil, il a maintenant deux mondes divergents et aucun moyen de les réconcilier. Corriger cela n'est pas un problème de rendu, c'est un problème d'identité de compte.
Bien faire les choses vous-même implique d'implémenter des flux de connexion, un stockage de sauvegarde côté serveur, et — la partie que tout le monde sous-estime — la gestion des conflits quand deux appareils écrivent dans le même emplacement de sauvegarde. Un modèle de lecture/écriture conscient des révisions, où le client compare les versions et résout les conflits explicitement, est la seule version qui survit au contact des vrais utilisateurs. Construire cela de zéro est un travail de plusieurs semaines ; horizOn fournit une sauvegarde cloud liée au compte avec lectures et écritures conscientes des révisions, exactement pour ce cas, ainsi que l'authentification par e-mail, anonyme, Google et Apple, afin que la même identité de joueur soit conservée entre les lunettes et le téléphone.
Quel que soit le backend que vous utilisez, décidez de la politique de conflit avant de livrer. La règle du dernier-écrit-gagne détruit silencieusement la progression. Demander au joueur vaut mieux que de perdre des données.
Bonnes pratiques pour livrer sur XREAL AURA
- Concevez pour la lumière ambiante. Testez chaque panneau d'UI en extérieur à midi et dans une pièce sombre. Si votre texte devient illisible dans l'un ou l'autre cas, augmentez le contraste et ajoutez un léger contour lumineux plutôt qu'une ombre sombre — les ombres ne font rien sur un écran transparent.
- Gardez les conteneurs petits et redemandables. Un volume de 60 cm est plus facile à placer de manière fiable pour le système qu'un volume de 2 m. Supposez que chaque conteneur peut être perdu à tout moment et écrivez le chemin de récupération en premier, pas en dernier.
- Plafonnez agressivement votre budget de rendu. Ce sont des lunettes, pas un GPU de bureau. Visez un temps de frame sous 11 ms (classe 90 Hz) avec l'anti-aliasing temporel désactivé au profit du MSAA, qui coûte moins cher aux résolutions spatiales.
- Mettez l'UI dans des panneaux, le contenu dans des volumes. Ne combattez pas la logique de placement du système pour le texte. Réservez les volumes aux choses avec une vraie profondeur que le joueur inspecte sous plusieurs angles.
- Vérifiez sur l'appareil avant chaque étape clé. L'éditeur sur lunettes rend cela peu coûteux. Les résultats du simulateur ne révéleront pas la dérive d'ancrage, les échecs de luminance ou le comportement de perte de conteneur.
Passer à l'étape suivante
L'éditeur sur l'appareil est le véritable point fort ici. Il fait passer la boucle d'itération spatiale de quelques minutes à quelques secondes, et c'est la différence entre ajuster un design et le deviner.
Commencez par installer l'éditeur et l'application compagnon Gradle sur AURA, puis reconstruisez un petit projet existant en scène spatiale plutôt que de partir de zéro — vous ferez remonter immédiatement les problèmes d'ancrage et de luminance sur du contenu que vous comprenez déjà. Ensuite, ajoutez un conteneur volume 3D et un panneau d'UI, et stabilisez les deux sur un cycle de suspension/reprise. Une fois que cela tient, vous êtes prêt à concevoir pour la plateforme au lieu de la combattre.
Si l'état persistant du joueur multi-appareils est sur votre liste, horizOn gère la sauvegarde cloud liée au compte avec résolution de conflits côté client, afin que votre session spatiale et votre session sur écran plat restent en accord.
Source : Prêt pour XREAL AURA