vr-app/docs/01-phase0-setup-unity.md
Thomas Fransolet 0310d28b5e Canal VR Meta Quest : projet Unity, viewer web et documentation
Premier commit du cinquième front. Trois parties :

- `unity/MyInfoMateVR/` : le projet Unity (6000.0.83f1, URP, Meta XR SDK 205),
  un APK unique pour tous les clients. Menu flottant à sélection au regard,
  appairage, chargement de scène GLB, POI, cache de contenu, télémétrie.
- `unity-overlay/` : les mêmes scripts à recopier sur un projet Unity neuf, avec
  les pièges rencontrés consignés dans son README.
- `viewer/` : viewer et éditeur de scène web autonome (Vite, TypeScript,
  three.js), partagé avec les autres fronts.
- `docs/` : état des lieux, setup Unity, décisions d'architecture et plan
  d'exécution en 9 étapes.

La scène est décrite par un `scene.json` poussé par `adb push` : l'app le
préfère à celui embarqué dans l'APK.

Les binaires (GLB, textures de l'échantillon Sponza, DLL Meta XR) passent par
Git LFS dès ce premier commit — les y faire entrer après coup demanderait de
réécrire l'historique. Les artefacts régénérés par l'éditeur et par CMake
(`Library/`, `.utmp/`, Burst debug) sont ignorés.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 15:26:07 +02:00

13 KiB

Phase 0 — Setup Unity pour Meta Quest, à partir de zéro

Écrit pour quelqu'un qui n'a jamais ouvert Unity. Chaque chemin de menu est donné en entier.

⚠️ Unity n'est pas installé sur cette machine (vérifié le 2026-08-31, toujours vrai). Je ne peux donc rien compiler ni tester : ce guide est vérifié sur la doc et l'expérience du SDK, pas par une exécution. Compte 2 à 4 allers-retours sur les versions de packages Meta, qui bougent vite d'une release à l'autre.

⚠️ Les numéros de version ci-dessous sont ceux que je connais. Avant d'installer, ouvre la page de compatibilité Meta (developers.meta.com → Unity → Requirements) et prends la version d'Unity qui y est marquée recommandée. Si elle diffère, c'est elle qui gagne, pas ce document.


Ce que je peux produire, et ce que tu dois cliquer

Je peux générer en fichier Tu dois le faire à la main dans l'éditeur
Packages/manifest.json (la liste des packages) Installer Unity Hub et Unity
Tous les scripts C# (Assets/Scripts/**) Créer le projet (le template)
Un script d'éditeur qui construit la scène par code Le premier clic sur Build And Run
.gitignore Unity Activer le mode développeur sur le casque
Les fichiers de configuration texte lisibles (.asmdef, JSON) Les cases de Project Settings (voir §5)
Les cases de XR Plug-in Management (§6)

Pourquoi je ne génère pas les ProjectSettings/*.asset ni les .unity : c'est du YAML Unity avec des GUID et des fileID internes. Écrit à la main, ça produit un projet qui s'ouvre mais dont un réglage sur deux est silencieusement faux — le pire des cas, parce que ça ne plante pas. Les réglages se font à l'écran, une fois, en 15 minutes. La scène, en revanche, je peux la construire par code via un script d'éditeur ([MenuItem]) : c'est lisible, versionnable et rejouable.


1. Installer Unity Hub et Unity

  1. Télécharge Unity Hub : unity.com/download. C'est le lanceur ; Unity lui-même s'installe depuis lui.
  2. Crée un compte Unity (gratuit) et prends la licence Personal dans le Hub : Hub → icône compte (haut droite) → Manage licenses → Add → Get a free personal license.
  3. Dans le Hub : Installs → Install Editor.
  4. Choisis une version LTS — au moment d'écrire, la ligne recommandée par Meta est Unity 6 LTS (6000.0.x). Prends la dernière 6000.0.xxf1 de la liste LTS.

    Pourquoi LTS : support 2 ans, et surtout c'est la seule ligne que Meta teste. Une version .a/.b (alpha/beta) te fera perdre des journées sur des bugs qui ne sont pas les tiens.

Modules à cocher — c'est l'écran à ne pas rater

À l'écran Add modules, coche :

  • ☑️ Android Build Support — et déplie-le, les deux sous-modules ne sont pas cochés par défaut selon les versions :
    • ☑️ OpenJDK
    • ☑️ Android SDK & NDK Tools
  • ☑️ Documentation (optionnel, pratique hors ligne)

Ne coche pas iOS, WebGL, Linux : c'est des Go pour rien.

Si tu oublies un sous-module : Hub → Installs → ⚙️ sur la version → Add modules. Rien n'est perdu, mais Unity te dira « No Android module loaded » sans expliquer lequel manque.


2. Créer le projet

  1. Hub → Projects → New project.
  2. Template : 3D (Built-In Render Pipeline) ou Universal 3D (URP) ? → URP. Meta recommande URP pour Quest : le Forward+ et le rendu mono-passe stéréo y sont optimisés, et l'essentiel de la doc Meta récente le suppose. Prends Universal 3D.
  3. Nom du projet : MyInfoMateVR.
  4. Emplacement : …/GITEA/vr-app/unity/.
  5. Create project. Premier lancement : 2 à 5 minutes.

Tu obtiens un dossier avec Assets/, Packages/, ProjectSettings/, Library/. Library/ ne se versionne jamais — c'est du cache, plusieurs Go. Le .gitignore s'en charge.


3. Le .gitignore (je le génère)

Fichier à créer à la racine de vr-app/ — voir ../.gitignore une fois généré. L'essentiel : Library/, Temp/, Obj/, Build/, Logs/, UserSettings/, *.csproj, *.sln.

⚠️ Git LFS : les .glb, .fbx, .png et .mp4 sont des binaires lourds. Si le repo doit un jour contenir des assets, active LFS avant le premier commit d'un binaire — après, c'est une réécriture d'historique.


4. Les packages (je génère Packages/manifest.json)

Trois familles :

4.1 XR — installés par l'éditeur

  • com.unity.xr.openxrOpenXR Plugin, la couche standard.
  • com.unity.xr.interaction.toolkit — optionnel si tu utilises l'Interaction SDK de Meta.

Window → Package Manager → Unity Registry → chercher « OpenXR Plugin » → Install.

4.2 Meta XR SDK — le point qui bouge le plus

Meta distribue son SDK de deux façons selon les versions : par l'Asset Store (« Meta XR All-in-One SDK ») ou par un registre npm déclaré dans manifest.json. Les packages qui comptent :

Package Rôle
com.meta.xr.sdk.core Meta XR Core SDK — obligatoire : caméra, tracking, passthrough
com.meta.xr.sdk.interaction.ovr Interaction SDK — raycast contrôleur et hand tracking
com.meta.xr.sdk.all le méta-paquet qui tire tout (plus lourd)

Ce que tu dois faire à la main la première fois : Window → Asset Store → chercher « Meta XR All-in-One SDK » → Add to My Assets → Open in Unity → Package Manager → My Assets → Download → Import.

Puis Unity affiche un assistant Meta XR Project Setup Tool (Edit → Project Settings → Meta XR) qui liste les réglages non conformes avec un bouton Fix / Fix All. ➡️ Utilise-le. Il applique la moitié du §5 tout seul, et il est à jour du SDK installé — donc plus fiable que ce document.

4.3 glTF — le cœur du pipeline

Ajoutés par Window → Package Manager → + (haut gauche) → Add package by name… :

Nom exact à coller Rôle
com.unity.cloud.gltfast glTFast — chargement de .glb au runtime
com.unity.cloud.ktx support KTX2 / Basis Universal des textures
com.unity.cloud.draco géométrie compressée Draco
com.unity.meshopt.decompress géométrie compressée Meshopt

Les trois derniers sont des dépendances optionnelles de glTFast : sans eux, un GLB compressé se charge en erreur silencieuse (mesh vide, texture rose). C'est exactement le genre de panne qui coûte une demi-journée — installe-les tout de suite, même si les premiers GLB ne sont pas compressés.


5. Configurer le build Android pour Quest — écran par écran

Fais d'abord tourner le Meta XR Project Setup Tool (§4.2), puis vérifie ce qui suit. Ce que l'outil corrige, tu n'as pas à le refaire.

5.1 Passer la plateforme en Android

File → Build Profiles (Unity 6 ; File → Build Settings avant Unity 6) → sélectionne AndroidSwitch Platform. ⏱️ Le premier switch réimporte tous les assets : 5 à 20 minutes. C'est normal, ne l'interromps pas.

Dans le même écran : Texture Compression → ASTC.

5.2 Player Settings

Edit → Project Settings → Player, onglet Android (l'icône robot) :

Section Réglage Valeur
Other Settings → Rendering Color Space Linear
Auto Graphics API décoché
Graphics APIs Vulkan uniquement — supprime OpenGLES3 de la liste
Multithreaded Rendering ☑️
Other Settings → Identification Package Name be.unov.myinfomate.vr (jamais le com.DefaultCompany par défaut)
Minimum API Level 32 (Android 12L) — exigé par Horizon OS récent
Target API Level la plus haute proposée (34+)
Other Settings → Configuration Scripting Backend IL2CPP (Mono ne produit pas d'APK Quest valide)
Target Architectures ☑️ ARM64 seulement — décoche ARMv7
Active Input Handling Both — le plus sûr : l'OVRInput de Meta est en legacy, le reste de l'écosystème en new Input System
Resolution and Presentation Default Orientation Landscape Left
Publishing Settings Custom Main Manifest ☑️ si tu dois ajouter des permissions à la main

5.3 Quality

Edit → Project Settings → Quality : garde un seul niveau pour Android, et mets-y : Anti Aliasing = 4x Multi Sampling (le MSAA est quasi gratuit sur le GPU mobile du Quest, et c'est ce qui fait la différence entre « propre » et « ça scintille »), Shadows = Hard Shadows Only ou aucune.


6. XR Plug-in Management

Edit → Project Settings → XR Plug-in Management :

  1. S'il propose Install XR Plug-in Management, clique.
  2. Choisis l'onglet Android (l'icône robot) — ⚠️ pas l'onglet PC. C'est l'erreur n°1 : tout configurer sur PC et obtenir un APK sans VR.
  3. ☑️ OpenXR
  4. Sous OpenXR (sous-entrée du menu de gauche), onglet Android :
    • Enabled Interaction Profiles+Oculus Touch Controller Profile
    • OpenXR Feature Groups☑️ Meta Quest (ou Meta Quest Support selon la version)
  5. Un triangle jaune ⚠️ à côté d'un réglage est cliquable : il ouvre un correcteur automatique. Aucun triangle ne doit rester avant de builder.

7. Activer le mode développeur sur le casque

À faire une seule fois, mais dans cet ordre — l'étape 1 est celle qu'on oublie :

  1. Crée une organisation développeur : developers.meta.com → connecte-toi avec le compte Meta du casqueCreate organization. Sans organisation, le toggle de l'étape 3 n'apparaît pas.
  2. Application Meta Horizon sur le téléphone → Devices (ou Appareils) → sélectionne le casque → assure-toi qu'il est connecté.
  3. Headset settingsDeveloper mode☑️.
  4. Redémarre le casque.
  5. Branche le casque en USB-C au PC. Mets le casque sur la tête : une popup « Autoriser le débogage USB ? » apparaît dans le casque, pas sur le PC. Coche Toujours autoriser et accepte. Tant que ce n'est pas fait, adb devices affiche unauthorized.
  6. Vérifie côté PC :
    adb devices
    
    adb se trouve dans le SDK Android installé par Unity : C:\Program Files\Unity\Hub\Editor\<version>\Editor\Data\PlaybackEngines\AndroidPlayer\SDK\platform-tools\ Ajoute ce dossier au PATH, tu t'en serviras tous les jours.

Alternative confortable : Meta Quest Developer Hub (MQDH), l'outil desktop de Meta. Il gère l'appairage, l'installation d'APK par glisser-déposer, la capture vidéo de ce que voit le casque (précieux pour montrer une démo à un client) et les logs. Recommandé.


8. Hello World VR — le seul test qui compte

But : voir une scène en stéréo dans le casque et bouger la tête. Rien d'autre. Tant que ça ne marche pas, tout le reste est théorique.

Ce que tu fais à la main

  1. File → New Scene → Basic (URP) → sauvegarde en Assets/Scenes/Hello.unity.
  2. Supprime la Main Camera de la hiérarchie (le rig VR apporte la sienne).
  3. Ajoute le rig : menu Meta → Tools → Building Blocks → glisse Camera Rig dans la scène. (Si le menu Meta n'existe pas, le SDK n'est pas importé — retour au §4.2.)
  4. Clic droit dans la hiérarchie → 3D Object → Cube, place-le à Position (0, 1.5, 2), Scale (0.3, 0.3, 0.3). C'est ton repère visuel.
  5. File → Build Profiles → vérifie que Assets/Scenes/Hello.unity est dans la liste des scènes et cochée (bouton Add Open Scenes si elle n'y est pas).
  6. Casque branché et autorisé → Build And Run.
  7. Premier build : 10 à 30 minutes (IL2CPP compile tout le code natif). Les suivants : 1 à 3 min.

Critère de validation

Le cube est devant toi, en relief, et il reste immobile dans l'espace quand tu bouges la tête (pas collé au regard). Si le cube suit ta tête, le rig n'est pas correctement en place.

Panne la plus fréquente

Symptôme Cause
L'app s'ouvre en écran plat flottant, pas en VR XR Plug-in Management configuré sur l'onglet PC au lieu d'Android (§6.2)
adb: device unauthorized La popup d'autorisation n'a pas été acceptée dans le casque (§7.5)
Build échoue sur « No Android module » Sous-modules OpenJDK / SDK-NDK non cochés (§1)
Écran noir au lancement Graphics API : OpenGLES3 encore présent avant Vulkan (§5.2)
Tout est rose Shader non compatible URP — l'objet vient d'un import Built-In

9. Étape suivante immédiate

Une fois le cube visible, la vraie étape 1 du projet (cahier des charges §PHASE 3) :

  1. Un monde Marble généré à la main sur le site de World Labs, exporté en mesh GLB.
  2. Ce GLB posé dans Assets/StreamingAssets/ et chargé au runtime par glTFast — pas glissé dans la scène comme un asset d'éditeur. C'est toute la différence : le chargement runtime est ce qui permettra plus tard de télécharger un monde depuis le manager sans rebuild.
  3. Un second GLB de personnage posé dedans, à l'échelle, avec un idle.
  4. Vu dans le casque.

Aucun backend n'est nécessaire pour ces quatre points — c'est ce qui les rend faisables tout de suite, en parallèle de tout le reste. Les scripts C# de chargement, je les génère quand tu me dis que le cube est passé.