Limen
Le rig du personnage et l'exporteur d'animations vers Unity, pour le jeu de Giulia
Le projet et la collaboration
Limen est le projet de Giulia, un jeu Unity d’escape game dont le dépôt est le sien : contrôleur du joueur, caméras, décor, shaders (pixel art, dithering). Giulia m’a demandé de faire le rig du personnage et son morph, puis j’ai écrit l’outil qui fait passer ses animations de Blender à Unity. C’est une collaboration : je suis intervenu sur la partie animation.
Cette fiche ne parle donc que de ces deux outils. Le reste du jeu n’est pas de moi.
Le rig
Le personnage est un raton laveur, et il existe en deux morphologies, enfant et adulte. Le rig est construit avec Rigify, une fois par morphologie, puis un squelette de déformation les relie : chacun de ses os suit à la fois l’os enfant et l’os adulte, et un seul curseur (morph_blend, de 0 à 1) dose le mélange. Les proportions changent donc en direct, y compris sur la pose en cours.
Les bras et les jambes ont chacun un curseur IK/FK. J’ai écrit un panneau Blender qui regroupe tout dans le volet latéral : boutons Child et Adult pour afficher l’une ou l’autre morphologie, curseur de morphologie, boutons de visibilité des calques de contrôles, et pour chaque membre le curseur IK/FK avec deux boutons de calage. « IK → FK » et « FK → IK » recalent un mode sur l’autre pour basculer sans faire sauter la pose.
Ce calage, je ne l’ai pas réécrit : j’ai repris le code de Rigify (licence GPL, mentionnée dans le fichier) et je l’ai rendu autonome. Le rig généré par Rigify embarque normalement son propre script d’interface, absent de ma scène.
L'exporteur Unity
Dans Blender, les clips sont des actions, que je gère dans un second panneau : liste de clips, ajout, suppression, duplication, réordonnancement. Chaque clip peut être copié en miroir (les courbes d’un os gauche passent sur l’os droit, avec les axes qu’il faut inverser) ou à l’envers. Un clip vide s’exporte en pose fixe d’une image.
Le bouton d’export écrit un fichier .anim par clip, nommé ANIM_<Personnage>_<nom>, directement dans le dossier d’animations du projet Unity. Les noms viennent d’une convention : l’armature de déformation s’appelle DEF-<Perso>, le rig de contrôle RIG-<Perso>, et l’outil retrouve le personnage à partir de l’objet actif, sans nom écrit en dur.
Pour chaque image, l’exporteur lit la pose finale de chaque os (contraintes et drivers appliqués), la convertit dans le repère d’Unity et l’écrit en courbes de position, rotation et échelle. Les blendshapes du maillage deviennent des courbes blendShape.<nom>, ce qui fait suivre à Unity la forme adulte en même temps que les os.
Le modèle suit le même chemin : « Update Model » écrit un fichier .racmodel (maillage, squelette, blendshapes, yeux et nez rigides), et un petit importeur C# côté Unity le transforme en vrai asset, comme un FBX. Modèle et animations passent par la même conversion, donc ils restent d’accord entre eux.
Les choix et leurs raisons
Mon premier export passait par des FBX. J’ai calibré une conversion contre ces FBX de référence, avec toute une série de scripts de mesure, puis j’ai arrêté : un simple changement de base (Blender est en Z vers le haut, Unity en Y), appliqué de la même façon au modèle et aux animations, rend la calibration inutile. Plus de FBX dans la boucle, plus d’écart à rattraper.
L’échelle non uniforme des os pose problème : une fois exportée en position, rotation et échelle, elle écrase les os enfants (du cisaillement) et Unity ne sait pas le rendre. J’ai donc retiré l’étirement des membres (IK_Stretch à 0 par défaut, et la translation de la tête bornée par une contrainte). Les os du squelette de déformation sont déconnectés, de sorte que les proportions adultes viennent de la position des articulations et pas d’une mise à l’échelle.
La forme adulte du corps n’est pas qu’une affaire d’os. Je sculpte la cible à la main, puis un script la « dé-pose » contre la pose adulte du squelette pour en tirer une clé de forme (Adult_shape) pilotée par le même curseur que les contraintes. Unity reçoit les os et cette forme, et retrouve le sculpt.
Ce que ça change
Avant, passer un clip de Blender à Unity voulait dire passer par un FBX, avec un écart de conversion à rattraper à chaque fois. Maintenant, un bouton écrit un .anim par clip, blendshapes compris, directement dans le dossier d’animations du projet Unity. Giulia anime dans Blender et retrouve ses clips dans Unity.
Les limites
L’exporteur échantillonne chaque image : les courbes sont écrites avec des tangentes quasi linéaires, pas avec les courbes de Bézier d’origine. Les os feuilles gardent leur échelle non uniforme (joues, yeux, sourcils), les autres sont aplatis. Le dossier de sortie est fixé dans la configuration, relatif au fichier .blend. Je ne l’ai essayé que sur un personnage, avec quelques clips d’essai et leurs versions en miroir et à l’envers. Le panneau du rig ne couvre que ce personnage : les noms d’os des membres sont écrits dans un fichier de constantes.
État du projet
Le projet est en cours. Mon dernier ajout date du début de juillet : le rig, les blendshapes et l’exporteur marchent sur le personnage d’essai, et la prise en charge du morph dans l’exporteur est récente.
Liens
Équipe
- Giulia : le projet, le gameplay, le décor et les shaders. Giulia m’a confié le rig du personnage et son morph.
- Moi : le rig, le morph, l’exporteur d’animations vers Unity.