Que fait R15) ?
Vous créez un mouvement sous forme d'une petite spécification de mouvement JSON : une poignée de poses clés écrites en termes anatomiques ("bras droit supérieur 90° vers l'avant", "genou plié à 60°"). Le moteur intégré fait tout ce qui est sujet à erreur à la main : les calculs d'articulations Roblox pour les deux rigs, l'interpolation, le maintien des pieds au sol, un visualiseur 3D, des avertissements de cohérence et l'exportation des images clés cuites.
L'utilisateur juge le résultat en le regardant, donc la boucle est : planifier les phases → écrire la spécification → construire → regarder le storyboard vous-même → corriger → livrer l'aperçu + les images clés. Ne sautez pas l'étape de visualisation ; des numéros de pose qui semblent corrects sur le papier sont souvent visiblement faux (un bras traversant la poitrine, un coup de pied qui n'atteint jamais le ballon).
Flux de travail
- Définir le mouvement. Rig (R6 ou R15 ; ne demandez que si cela ne peut vraiment pas être déduit, sinon par défaut prenez R15 et dites-le), latéralité, boucle ou one-shot, durée approximative, et quels accroches de gameplay sont nécessaires (image d'impact, lâcher de balle, pas). Commencez directement à construire pour une demande claire.
- Décomposer en phases avant d'écrire des nombres. Presque toute action est : prêt → anticipation → action → suivi → récupération. Lisez
references/motion-cookbook.mdpour le genre que vous traitez (combat, sports, cycles de locomotion, acrobaties, spécificités R6) ; il contient des tableaux de synchronisation et des recettes de poses. - Écrire la spécification dans
<nom>.json. Commencez à partir du fichier le plus proche dansexemples/plutôt que de zéro. - Construire :
node <skill>/scripts/ranim.cjs <nom>.json --out out(plusieurs spécifications peuvent être passées ; elles deviennent des onglets dans un aperçu). Nécessite seulement Node, pas de paquets. - Lire le rapport imprimé sur stdout. Il liste où se trouvent la tête, les mains et les pieds à chaque image clé (studs : R = à droite du personnage, U = au-dessus du sol, F = devant) et imprime des lignes
WARN. Utilisez les positions pour vérifier l'intention : le poing est-il vraiment devant la poitrine, le pied est-il à la hauteur du ballon ? - Regarder
out/storyboard-<Nom>.pngavec l'outil de lecture (chaque image clé vue en 3/4 et de côté). Si aucun PNG n'a été produit, faites une capture d'écran deout/aperçu.htmlavec un navigateur sans tête ou lisez le SVG. Comparez chaque panneau avec la phase que vous aviez prévue. - Corriger et reconstruire jusqu'à ce que les poses soient clairement lisibles et que les avertissements aient disparu ou soient consciemment acceptés. Deux ou trois itérations sont normales.
- Livrer : l'
out/aperçu.htmlinteractif (publiez-le comme artefact ou envoyez le fichier), ainsi queout/<Nom>.rbxmxetout/<Nom>.lua. Montrez l'image du storyboard en ligne si possible. Expliquez brièvement à l'utilisateur comment l'importer dans Studio (ci-dessous) et quels événements d'animation existent.
Spécification de mouvement
{
"name": "JabCross",
"title": "Combo jab-cross",
"rig": "R15",
"priority": "Action",
"loop": false,
"description": "Une ou deux phrases affichées à côté de l'aperçu.",
"keys": [
{ "t": 0, "label": "garde", "note": "Affiché dans la liste des phases.",
"pose": { "UpperTorso": { "turnR": 10, "bendFwd": 8 },
"LeftUpperArm": { "fwd": 50, "out": 8 }, "LeftLowerArm": { "bend": 120 },
"LeftFoot": "flat" } },
{ "t": 0.1, "label": "jab", "ease": "out", "copy": "garde",
"pose": { "LeftUpperArm": { "fwd": 86, "in": 22 }, "LeftLowerArm": { "bend": 6 } } },
{ "t": 0.8, "label": "récupération", "copy": "garde" }
],
"markers": [ { "t": 0.1, "name": "Hit", "value": "jab" } ],
"props": [ { "type": "ball", "radius": 0.6, "color": "#e07a2c", "keys": [ ... ] } ]
}
(Les commentaires sont uniquement pour l'explication ; le fichier doit être du JSON brut.)
Champs optionnels de niveau supérieur : fps (par défaut 30 ; utilisez 60 pour les mouvements très rapides), duration (par défaut la dernière image clé), grounding ("off" pour contrôler la hauteur à la main), mirror: true (inverser tout le clip gauche/droite, par exemple une version du pied gauche), endKeyframe: true.
Images clés
tsecondes (arrondi à une image). La première image clé est à 0.posemappe nom d'articulation → canaux en degrés. Une articulation omise dans une image clé est simplement interpolée à travers cette image clé, donc les images clés intermédiaires peuvent ne mentionner que les articulations qui comptent. Une articulation jamais mentionnée reste au repos et n'est pas exportée ; une première mentionnée après l'image clé 0 part du repos (0°).copy: l'étiquette ou l'index d'une image clé antérieure. La pose commence comme une copie etposeremplace des parties de celle-ci."mirror": trueaveccopyéchange la gauche et la droite, c'est ainsi que les cycles de marche/course sont fabriqués à partir d'une demi-foulée.easefaçonne le segment quittant cette image clé :smooth(par défaut, s'adoucit naturellement sans dépassement),linear,in(commence lentement, finit vite : remontées mécaniques se libérant en coup),out(commence vite, s'installe : impacts),inOut,hold,overshoot,anticipate,bounce,elastic.lift: hauteur en studs du point le plus bas du corps au-dessus du sol à cette image clé (par défaut 0). C'est ainsi que les sauts sont créés ; voir Grounding.
Articulations et canaux
Les angles sont anatomiques et le même mot signifie la même chose des deux côtés du corps, donc une pose en miroir n'a besoin d'aucun changement de signe. Chaque canal a un alias de direction opposée ; utilisez celui qui se lit naturellement.
| Articulations | Canaux (alias pour la direction opposée) |
|---|---|
Racine : LowerTorso (R15), Torso (R6) | bendFwd (bendBack), turnL (turnR), leanR (leanL), moveFwd (moveBack), moveR (moveL), moveUp (moveDown) en studs |
Colonne vertébrale : UpperTorso, Head | bendFwd (bendBack), turnL (turnR), leanR (leanL) |
Membres supérieurs : Left/RightUpperArm, Left/RightUpperLeg ; R6 Left Arm, Right Arm, Left Leg, Right Leg | fwd (back) balance le membre vers l'avant/le haut, out (in) loin du / à travers le corps, twistOut (twistIn) le roule sur sa propre longueur |
Left/RightLowerArm, Left/RightLowerLeg | bend : coudes et genoux dans leur direction naturelle (0 = droit) |
Left/RightHand, Left/RightFoot | fwd (back), out (in), twistOut (twistIn). Les pieds acceptent aussi la chaîne "flat" |
Repères : bras fwd: 90 pointe tout droit devant, fwd: 180 tout droit vers le haut, out: 90 est une pose en T. Jambe fwd: 90 est un coup de pied avant à hauteur de taille. Les rotations se composent du parent à l'enfant, donc la rotation du torse emporte les bras avec elle ; tournez la Head dans la direction opposée pour garder les yeux sur la cible.
R6 a six parties et pas de coudes, genoux, mains ou pieds, donc la silhouette provient des angles du torse et des membres entiers ; exagérez un peu. Les noms des membres R6 contiennent un espace ("Right Arm").
Grounding
Par défaut, le moteur abaisse ou élève la racine à chaque image de sorte que le point le plus bas du corps se trouve exactement à lift studs au-dessus du sol. Conséquences :
- Les accroupissements, fentes et grands écarts abaissent automatiquement les hanches ; ne réglez jamais manuellement la hauteur des hanches pour une pose debout.
"flat"sur un pied R15 résout la cheville de sorte que la plante repose à plat quelle que soit la position de la jambe. Utilisez-le pour chaque pied planté ; donnez des angles explicites ("back": 40= pointes de pied) pour les pieds en l'air ou sur la pointe des pieds.- Un saut correspond à des valeurs
liftsur les images clés aériennes (décollage petit, apex le plus grand, 0 à l'atterrissage). La rotation du corps dans les airs se fait sur la racine : un backflip est lebendBackde la racine allant de 0 → 360 à travers les images clés (les angles sont continus, donc 360 est un tour complet, pas "retour à 0"). moveUpsur la racine est ignoré tant que le grounding est activé. Mettez"grounding": "off"uniquement pour des choses comme la nage ou l'escalade où le sol n'est pas pertinent.- En jeu, les sauts et les dashes sont normalement déplacés par le contrôleur de personnage, pas par l'animation. Pour une animation destinée à être jouée pendant un saut de gameplay, posez le corps et laissez
liftà 0. UtilisezliftetmoveFwdpour les émotes autonomes, les attaques avec un saut, et les flips. Si le clip se termine déplacé par rapport à son point de départ, le rapport avertit, car Roblox ramène le corps à sa position d'origine lorsque la piste s'arrête.
Marqueurs et accessoires
markersdeviennent desKeyframeMarkers, lus en jeu avectrack:GetMarkerReachedSignal("Hit"). Placez-en un sur chaque image que le gameplay prend en compte : fenêtres d'impact, contact ou lâcher de balle, pas, signaux sonores.propssont réservés à l'aperçu (ils ne sont pas exportés) et existent pour que le mouvement puisse être jugé par rapport à la chose avec laquelle il interagit.type: "ball"avecradius, ou tout autre type pour une boîte avecsize: [x, y, z](une épée est une boîte longue et fine).atest soit un nom de partie (l'accessoire suit cette partie ;offset: [right, up, fwd]dans les axes propres de la partie) soit un point fixe[right, up, fwd]en studs à partir du point au sol sous le personnage. Avec plusieurskeys, l'accessoire se déplace entre les ancres ;arcajoute une élévation parabolique au segment quittant cette image clé (un tir ou une passe). Voirexemples/jump_shot.jsonetexemples/soccer_kick.json.
À quoi ressemble un bon résultat
- Silhouettes lisibles. Dans le storyboard, chaque image clé doit être reconnaissable par son contour seul. Si deux images clés voisines se ressemblent, l'une d'elles ne fait aucun travail.
- Contraste dans le timing. Anticipation lente, action très rapide (2 à 4 images), une courte tenue sur le suivi, récupération plus lente. Un espacement égal entre les images clés est la raison la plus courante pour laquelle un mouvement semble sans poids.
- Tout le corps participe. La puissance commence aux pieds et aux hanches, puis la poitrine, puis l'épaule, puis la main ou le pied. Donnez aux hanches et à la poitrine une contre-rotation dans le remontage et laissez le bras éloigné équilibrer le bras proche.
- Les pieds restent en place. Un pied planté conserve ses numéros R et F dans le rapport d'une image clé à l'autre. S'il doit bouger, soulevez-le dans une image clé intermédiaire (un pas).
- Zéro avertissements, ou une raison pour chacun de ceux que vous gardez. Les limites sont les plages naturelles des articulations ; les dépasser signifie généralement qu'un canal différent était prévu.
Comment l'importer dans Roblox Studio
Donnez à l'utilisateur les deux voies et les noms des événements.
- Barre de commandes (le plus rapide) : sélectionnez le rig dans l'Explorateur, ouvrez Affichage → Barre de commandes, collez l'intégralité du contenu de
<Nom>.lua, appuyez sur Entrée. Le KeyframeSequence apparaît dansAnimSavesdu rig (ou dans ServerStorage si rien n'est sélectionné), d'où l'Éditeur d'Animation peut le charger pour le modifier. - Fichier : faites glisser
<Nom>.rbxmxdans la fenêtre Studio, ou cliquez avec le bouton droit sur un service → Insérer à partir d'un fichier. - Publication : pour le jouer dans un jeu en direct, il doit être téléchargé : ouvrez-le dans l'Éditeur d'Animation et publiez, ou cliquez avec le bouton droit sur le KeyframeSequence → Enregistrer sur Roblox, puis utilisez l'ID d'actif résultant dans un objet
AnimationetAnimator:LoadAnimation. Pour des tests locaux rapides dans Studio,game:GetService("KeyframeSequenceProvider"):RegisterKeyframeSequence(seq)retourne un ID temporaire. Les menus de Studio changent de temps en temps ; si une étape ne correspond pas à ce que l'utilisateur voit, dites-le et recherchez la formulation actuelle plutôt que d'insister.
L'exportation est cuite : une image clé par image avec interpolation linéaire, donc Studio joue exactement ce que l'aperçu montre sur n'importe quel rig de ce type. Seules les articulations que la spécification anime sont écrites, donc une animation du haut du corps seulement laisse les jambes libres pour la marche par défaut. La sortie R15 porte AuthoredHipHeight afin qu'elle se retarget sur des avatars d'autres proportions.
Fichiers
scripts/ranim.cjs— moteur, visualiseur et exportateur en un seul fichier. Utilisable aussi comme module :const R = require('.../ranim.cjs'); const c = R.compile(spec); R.report(c); R.sample(c, t).scripts/selftest.cjs— vérifie les calculs d'articulations par rapport à la formule Motor6D de Roblox. Exécutez-le après avoir modifié le moteur.exemples/—soccer_kick,jump_shot(sports avec accessoires de balle),jab_cross(combat R15),r6_sword_slash(combat R6 avec une arme),backflip(rotation complète du corps et un saut),r6_run(boucle en miroir).references/motion-cookbook.md— tableaux de synchronisation et recettes de poses par genre. Lisez la section pertinente avant de créer.