
Développeur Fullstack
Intégration complète de Supabase dans Unity WebGL avec Nuxt
Dans mon application RPGFitness.fr, j’ai intégré un jeu Unity WebGL directement dans une application Nuxt + Capacitor, tout en connectant le système de progression du joueur à Supabase.
Ce setup m’a permis de :
- gérer l’authentification du joueur via Supabase Auth,
- charger les stats du personnage depuis Supabase,
- envoyer ces données à Unity pour les combats,
- récupérer la progression (chapitres terminés) depuis Unity,
- maintenir une communication temps réel Nuxt → Unity → Nuxt via
postMessage.
C’est une architecture rare, mais extrêmement puissante.
🏗️ Architecture générale
Supabase ←→ Nuxt (Capacitor mobile) ←(postMessage)→ Unity WebGL
yaml Copier le code
- Nuxt gère l’authentification + les données du joueur.
- Unity WebGL gère le combat, les chapitres, la progression RPG.
- postMessage synchronise les deux environnements.
🔐 1. Authentification via Supabase (côté Nuxt)
Unity WebGL ne gère pas les secure cookies, ni Supabase Auth directement.
Donc Nuxt login → Unity reçoit juste les données nécessaires.
Après connexion, Nuxt charge :
- inventaire,
- totaux (dégâts / PV / armure),
- personnage sélectionné,
- niveau de chapitre.
Tout ceci est encapsulé dans une classe :
const Perso = new Personnage(account.uid, supabase); await Perso.getInventaire(); await Perso.recupererDetailsInventaire(); await Perso.calculerTotaux(); C’est ensuite Unity qui demande ces données.
🔁 2. Communication Unity → Nuxt avec postMessage Dans le WebGL, Unity appelle une fonction JS exportée :
#if UNITY_WEBGL && !UNITY_EDITOR DllImport("__Internal") private static extern void RequestCharacterData(); #endif Au lancement du jeu :
RequestCharacterData(); Ce qui déclenche dans le fichier HTML WebGL :
window.parent.postMessage({ type: "GET_CHARACTER_DATA", payload: { gameObjectName, methodName } }, "*"); Nuxt reçoit ce message :
window.addEventListener("message", async (event) => { if (event.data.type === "GET_CHARACTER_DATA") { // chargement du personnage depuis Supabase... iframe.contentWindow.postMessage({ type: "CHARACTER_DATA", payload: { gameObjectName, methodName, data: JSON.stringify(characterData) } }, "*"); } }); Nuxt renvoie alors les données RPG à Unity.
🎮 3. Réception des données dans Unity Unity reçoit via SendMessage :
public void ReceiveMessage(string message)
{
CharacterData character = JsonUtility.FromJson
GameManager.Instance.playerData = character;
// Chargement du chapitre correspondant
ChapterData chapter = chapterDataList.chapters
.Find(c => c.levelChapitre == character.levelChapitre);
} Unity se configure automatiquement avec les stats du joueur stockées dans Supabase.
📤 4. Envoyer la progression à Supabase (Unity → Nuxt) Lorsqu’un chapitre est terminé :
window.parent.postMessage({ type: "FROM_UNITY", payload: chapterLevel }, "*"); Nuxt reçoit :
account.level_chapitre = chapterLevel + 1;
const { updateUser } = useProfiles(); await updateUser(account.uid, { level_chapitre: chapterLevel + 1 }); Le niveau est mis à jour dans Supabase.
📱 5. Gestion du viewport sur mobile (Capacitor) Un point souvent oublié : Unity WebGL dans une app mobile Capacitor casse le viewport mobile.
J’ai donc ajouté un système avancé qui :
détecte iOS/Android,
compense la hauteur du menu custom,
surveille visualViewport,
recalcule dynamiquement la hauteur utilisable.
Extrait :
function updateVh() {
containerHeight.value = window.innerHeight - CUSTOM_MENU_HEIGHT;
document.documentElement.style.setProperty(
"--real-vh",
${containerHeight.value * 0.01}px
);
}
Ce fix améliore énormément l’expérience mobile.
🚧 6. Limitations rencontrées & solutions ❌ Supabase JS non supporté dans WebGL → Solution : Nuxt fait les requêtes, Unity reçoit juste les données.
❌ SendMessage non fiable avant initialisation Unity → Solution : Attendre unityInstance :
if(window.unityInstance) { window.unityInstance.SendMessage(...); } ❌ Viewport mobile instable → Solution : Système basé sur visualViewport + recalcul dynamique.
❌ JsonUtility limité → Solution : Structures de données simples et typées.
🏆 Résultat final Grâce à cette architecture :
Le joueur est authentifié via Supabase.
Ses stats sont chargées depuis Nuxt.
Unity récupère et applique les données automatiquement.
Unity renvoie la progression à Supabase.
Le tout fonctionne sur Web, Android, et iOS.
Un vrai système RPG temps réel complet, basé sur une stack moderne.
🔗 Voir aussi 👉 Projet complet : https://rpgfitness.fr