Files
ProjectFGame/Docs/Plan_Conversion_MetaHuman.md
T
DodoandClaude Opus 5.5 ffaebfbd3e Conversion MetaHuman : os attach animé dans les traversées
Les warps de traversée (FrontLedge, BackLedge, BackFloor) prennent l'os
attach comme repère. Il n'était pas animé dans les séquences converties,
d'où une escalade qui montait au-dessus du bloc. Piste attach recopiée
depuis les originaux dans les 70 séquences concernées (escalade, mantle,
vault, hurdle, rattrapages, banc).

Vérifié en PIE : mantle 1 m et 1,5 m, escalade 2 m et 2,4 m à la bonne
hauteur.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 15:58:25 +01:00

15 KiB

Conversion du personnage Mover vers le squelette MetaHuman

Branche : metahuman-skeleton-conversion (dépôt origin = git.catrybenoit.dev/Dodo/ProjectFGame). Phase 1 (inventaire) faite le 2026-10-31.

Cible

  • MetaHuman unique du projet : « test »
    • corps /Game/Characters/MEtahuman/Unpacked/test/Body/SKM_test_BodyMesh, squelette partagé /Game/MetaHumans/Common/Female/Medium/NormalWeight/Body/metahuman_base_skel ;
    • visage SKM_test_FaceMesh (squelette Face_Archetype_Skeleton, piloté par ABP_Face) ;
    • Physics Asset PHYS_test (les hitboxes du pion sont déjà calibrées dessus).
  • Source : SK_UEFN_Mannequin (squelette de SKM_UEFN_Mannequin).

Inventaire

Os

UEFN MetaHuman
Os 95 342
Communs 78, même hiérarchie

Présents seulement côté UEFN, à ajouter au MetaHuman :

  • ik_hand_root, ik_hand_gun, ik_hand_l, ik_hand_r : IK des armes AST (WeaponIKGraph cible VB hand_r_ik_hand_l) ;
  • ik_foot_root, ik_foot_l, ik_foot_r : placement des pieds, OverlayGraph::DynamicTransitionCheck ;
  • weapon_l, weapon_r, props_root, prop_01, attach, poi ;
  • os virtuels : VB hand_r_ik_hand_l, VB hand_l_ik_hand_r, VB hand_r_prop_01, VB hand_l_prop_01.

unreal.SkeletonModifier (add_bone / commit_skeleton_to_skeletal_mesh) est disponible en Python.

Sockets à recréer (le MetaHuman n'en a aucun)

16 sockets UEFN :

  • palm_l_Socket, palm_r_Socket ;
  • RagdollTrace (spine_03) ;
  • prop_01_Socket, VB hand_r_prop_01_Socket ;
  • BackpackSocket (spine_03), SpineRifle (spine_05) ;
  • sur hand_r : Bumper, Shotgun, FlashlightSocket, Rifle ;
  • weapon_r_muzzle ;
  • sur head : HeadphoneSocket, HelmetSocket ;
  • foot_l_Socket, foot_r_Socket.

⚠️ Python ne sait pas nommer un socket : copier-coller dans l'éditeur de squelette (manuel, guidé), puis recaler les transforms par script.

Assets qui référencent le squelette UEFN (2147)

Type Nombre Où
AnimSequence 1845 1389 GASP (Characters/UEFN_Mannequin), 267 AST (Systems/Movement), 182 maison (Assets/Animations/humain), 7 AGIS
AnimMontage 224
PoseSearchSchema 30
BlendSpace / 1D / AimOffset 14 / 15 / 1
AnimBlueprint 8 SandboxCharacter_Mover_ABP, SandboxCharacter_CMC_ABP, ABP_AimingMaster_UEFN, ABP_UEFN_Mannequin_PostProcess, ABP_SkeletalEquippables, 3 calques AST
ControlRig 4
MirrorDataTable 3

Dépendants indirects (référencent des anims, pas le squelette) : 185 bases Motion Matching, 25 choosers.

Approche retenue : retarget en lot + remplacement des références

  1. Squelette MetaHuman
    • Ajouter les 17 os manquants via SkeletonModifier.
    • Ajouter les 4 os virtuels et les sockets.
    • Ajouter les groupes de slots d'animation (Grounded Slot…) via l'Anim Slot Manager, à la main.
  2. Retargeter dédié au lot (RTG_UEFN_to_MH_Batch), distinct de celui du runtime :
    • doigts en OneToOne avec la pose de retarget alignée (déjà réglé sur RTG_UEFN_to_MetaHuman_test) ;
    • pieds et jambes : objectifs IK mis à l'échelle ;
    • os IK :
      • ik_foot_* épinglés aux pieds ;
      • ik_hand_gun épinglé à hand_r en gardant l'écart source sans mise à l'échelle : l'arme garde sa taille, donc les cibles de main sur l'arme aussi ;
      • ik_hand_l / ik_hand_r copiés en local.
  3. Retarget en lot (IKRetargetBatchOperation), par blocs d'environ 200 assets avec sauvegarde entre chaque :
    • séquences, montages, blend spaces, aim offset et miroirs, dans un dossier miroir Content/Characters/MH/… ;
    • les références internes sont conservées (un montage pointe vers sa séquence convertie).
  4. Remplacement des références ancien → nouveau, pour que les 185 bases, les 25 choosers, les ABP et les notifies suivent sans être dupliqués.
    • Valider d'abord sur un petit lot.
    • Piège connu : consolidate_assets a déjà cassé des variables enum/struct ; contrôler avant de recharger.
  5. Schémas Motion Matching passés sur le nouveau squelette, puis reconstruction des index des 185 bases.
  6. AnimBP et calques retargetés sur metahuman_base_skel. Les Control Rigs travaillent par nom d'os, donc peu d'impact attendu. Recaler l'offset de la main gauche de WeaponIKGraph.
  7. Pion SandboxCharacter_Mover
    • mesh = SKM_test_BodyMesh, avec Face en enfant et le MetaHumanComponent ;
    • nouvel ABP ;
    • suppression de l'override visuel (VisualOverride, AC_VisualOverrideManager, ABP_GenericRetarget) ;
    • Inventory_Equipper revient à l'attache simple.
  8. Tests :
    • déplacements (Motion Matching), transitions ;
    • arc, fusil (visée, main gauche) ;
    • prone, nage, cover, interactions AST, push ;
    • mort et ragdoll, portrait d'inventaire, capture des hitboxes.
  9. Nettoyage : suppression du contenu UEFN seulement après validation (« compiler d'abord, nettoyer ensuite »).

Avancement

  • Phase 2 faite (2026-10-31) — squelette MetaHuman :

    • 13 os ajoutés par SkeletonModifier (342 → 355), calés sur la pose du MetaHuman :
      • ik_foot_l/r sur les pieds ;
      • ik_hand_gun et ik_hand_r sur hand_r, ik_hand_l sur hand_l ;
      • weapon_l/r avec le même décalage local que l'UEFN ;
      • props_root, prop_01, attach à l'origine, poi en (0, 150, 152.05).
    • 4 os virtuels aux noms identiques à l'UEFN. add_virtual_bone exige une AnimSequence du squelette : une anim temporaire a été créée puis supprimée.
    • 16 sockets copiés-collés à la main depuis l'UEFN, vérifiés par script : même os, même position relative.
    • Écarts en pose de référence :
      • sockets de main tournés de ~20°, parce que les mains du MetaHuman sont orientées autrement au repos. Le retargeter de conversion doit copier la rotation des mains depuis la source (BlendToSourceRotation = 1 sur LeftArm/RightArm), comme au runtime ;
      • casque ~10 cm plus haut (taille), sac à dos 7 cm plus près du dos : à vérifier à l'œil.
    • Sauvegarde : E:\projet\ProjectFv1_backup_mh_conversion_2026-10-31\.
    • Non-régression en PIE avec l'override actuel : visée OK, 0 erreur.
    • Groupes de slots : reportés après la conversion des montages, qui ajoute les slots au squelette.
  • Phase 3 faite (2026-10-31) — conversion des animations :

    • Retargeters de conversion dans Characters/MH/Retarget/ :
      • RTG_UEFN_to_MH_Batch (général) : copie de RTG_UEFN_to_MetaHuman_test + Root Motion sur l'os root de la source (set_source_root_bone("root"), l'ancien réglage pelvis faisait monter root à 91 cm) + Pin Bones (ik_foot_* ← pieds, ik_hand_gun/ik_hand_r ← hand_r, ik_hand_l ← hand_l, via set_bone_pair).
      • RTG_UEFN_to_MH_Weapon (armes AST) : en plus, op Weapon Goals (échelle 1) avant Run IK Rig ; IK Rigs dédiés IK_UEFN_Batch / IK_MH_Batch avec les chaînes IKHandGun/IKHandL/IKHandR (FK OneToOne + translation Absolute) ; pose de retarget de ik_hand_gun tournée de (P 17.6, Y -5.3, R 10.2) pour compenser l'écart de pose de repos des mains.
      • Bras : BlendToSource 1 / translation 0 / rotation 1.
    • Contrôles sur SMG_Aim_Pose et M_Neutral_Run_Loop_F :
      • main gauche à l'identique par rapport à la main droite (32,9 cm) ;
      • rotation des mains à moins de 1° de la source ;
      • racine au sol, avancée identique, pieds IK collés.
    • 2099 assets convertis, 0 échec, ~10 min :
      • 1845 séquences, 224 montages, 29 blend spaces, 1 aim offset ;
      • armes AST = noms SMG/Handgun/Sniper/Bullpup/Shotgun/Pistol/Rifle sous Systems/Movement.
    • Rangement : copies _MH créées à côté des originaux, puis déplacées dans Content/Characters/MH/<chemin d'origine> sans le suffixe. Montages et blend spaces pointent tous vers les copies (227 segments, 237 échantillons vérifiés).
    • Scripts et journal : p3_batch.py, p3_state.json, p3_move.py dans le scratchpad de la session.
    • Reste à faire avant les AnimBP :
      • groupes de slots du squelette MetaHuman, à la main dans l'Anim Slot Manager (protégés en Python). Slots utilisés : DefaultSlot, UpperBody, Curves, Spine, Head, Arm L, Arm R, Pelvis, Fire, Grounded Slot (groupe GroundedGroup), HitReactionSlot. Recopier la répartition du mannequin ;
      • Blend Profiles du squelette UEFN (FastFeet…, utilisés par l'ABP GASP) à recréer sur le MetaHuman.
    • Non converties : 3 MirrorDataTable, à refaire pour le squelette MetaHuman (miroir des anims prone/nage et GASP).
  • Phase 4 (2026-10-31 → 2026-11-04) — remplacement des références :

    • consolidate_assets(MH, [UEFN]) sur les 2099 assets, par lots de 100 avec sauvegarde entre chaque (~2 h 15).
      • L'éditeur affiche « Critical Failure to Consolidate Assets » et demande un redémarrage sans sauvegarde ; les références sont pourtant remplacées et enregistrées.
      • Effet réel : l'original UEFN devient un redirecteur vers la version MH (1963 sur 2099).
      • 136 n'ont pas été remplacés au premier passage (encore chargés en mémoire) ; relancés après redémarrage. Les 2099 sont maintenant des redirecteurs.
    • Python n'a pas de correction des redirecteurs : les 226 assets qui passaient encore par eux ont été réenregistrés, ils pointent directement vers Characters/MH. Plus aucun référenceur hors de la liste des 2099. Les redirecteurs partent avec le dossier UEFN au nettoyage.
    • Doublons : la consolidation a fait rajouter des montages par leurs notifies Branch In dans 4 bases (PSD_Traversal +3, PSD_SM_CMC_Idles +2, _Loops +10, _Transitions +32). Bases restaurées depuis le commit (éditeur fermé), puis réenregistrées.
    • Contrôle final : 185 bases, 2705 entrées toutes MetaHuman, 0 doublon ; 24 assets d'interaction sur les anims MH. Les index se reconstruisent à la première utilisation (pas d'API Python) → à vérifier en PIE.
    • Table miroir MetaHuman : Characters/MH/Characters/UEFN_Mannequin/Rigs/MDT_UEFN_Mannequin.
      • Mêmes règles de recherche/remplacement que l'UEFN, 355 lignes (349 paires gauche/droite, 6 os centraux sur eux-mêmes).
      • Piège : fill_data_table_from_json_string remet le squelette à vide, il faut le régler après.
      • MiroiDtCover (pion CMC seulement) et MDT_uefn (inutilisée) ne sont pas convertis.
    • 30 schémas Motion Matching passés sur metahuman_base_skel (ToolsetLibrary.set_object_properties sur Skeletons), PSS_Default/PSS_Idle avec la nouvelle table miroir.
  • Phase 5 faite (2026-11-05) — squelette et AnimBP :

    • Slots recréés à la main (Anim Slot Manager) : DefaultGroup + GroundedGroup (Grounded Slot).
    • 9 Blend Profiles recréés par unreal.SkeletonService (VibeUE : create_blend_profile / set_blend_profile_bone).
      • Os MetaHuman en plus (twists, correctifs, orteils) : valeur de l'os parent présent sur l'UEFN.
      • VibeUE crée en type Weight ; le type n'est pas modifiable en Python. Recréés à la main en Time (Pivot, FastFeet, FastFeet_InstantRoot, FastFeet_FastRoot) et en masque (UpperBody), puis remplis par script.
      • Masque : valeur par défaut 0 (UBlendProfile::GetDefaultBlendScale), donc le UpperBody MH (359 os à 0) équivaut à celui de l'UEFN.
    • 32 montages MH pointaient encore vers SK_UEFN_Mannequin:FastFeet_InstantRoot (blend_profile_in/out) → profil MH du même nom.
    • Table miroir : MDT_UEFN_Mannequin consolidée vers la version MH (ABP Mover, OverrideOverlayLayer, schémas).
    • 5 AnimBP passés en place sur metahuman_base_skel (set_editor_property("target_skeleton")) puis compilés : SandboxCharacter_Mover_ABP, OverlayGraph, OverrideOverlayLayer, InteractionIKGraph, ABP_AimingMaster_UEFN.
      • Blend Profiles des nœuds rebranchés (ObjectIterator(AnimGraphNode_Base), node.blend_profile) : Motion Matching → FastFeet_InstantRoot, Blend by Bool → FastHead_Weight.
      • Compilation dans l'ordre calques → ABP principal : 0 erreur. Reste l'avertissement VB RHS_WeaponTrace absent dans OverlayGraph, déjà présent avant (os absent de l'UEFN aussi).
    • Non touchés :
      • ABP_UEFN_Mannequin_PostProcess (mesh UEFN) ;
      • SandboxCharacter_CMC_ABP (supprimé au nettoyage) ;
      • ABP_SkeletalEquippables (utilisé par ItemMesh_Skeletal, à voir selon le squelette des items).
    • Control Rigs (CR_UEFN_Mannequin_FullBodyIK, pieds, escalade, interaction, collision d'arme) : gardent la hiérarchie UEFN, mêmes noms d'os → à valider en PIE ; réimporter la hiérarchie MH si besoin.
    • Recalage de la main gauche de WeaponIKGraph : reporté après la phase 6 (il faut le pion MetaHuman en PIE).
  • Phase 6 (2026-11-05) — pion SandboxCharacter_Mover sur le MetaHuman :

    • SkeletalMesh = SKM_test_BodyMesh, AnimBP SandboxCharacter_Mover_ABP.
      • Le composant était en mode Animation Single Node (idle en boucle) : repassé en AnimationBlueprint.
    • Ajout de Face (enfant de SkeletalMesh, SKM_test_FaceMesh + ABP_Face) et du composant MetaHuman (MetaHumanComponentUE), réglages copiés de BP_VisualOverride_MetaHuman, bodyComponentName = SkeletalMesh.
    • Composant VisualOverride retiré. Les systèmes qui en dépendaient retombent sur le mesh du pion :
      • AC_VisualOverrideManager : boucle vide, les hitboxes restent sur SkeletalMesh (déjà calibrées sur PHYS_test) ;
      • BP_Item_OutfitPiece_Base : branche sans override → GetComponentByClass(SkeletalMeshComponent) = SkeletalMesh (vérifié en PIE) ;
      • portrait d'inventaire : ShowOnlyActorComponents(self) inclut corps et visage.
    • Inventory_Equipper::Attach Item to Owner : bloc de réattache au Body du MetaHuman supprimé (17 nœuds), l'arme reste sur le socket du mesh du pion.
    • PIE (MapDev1) : AnimBP actif, 2 m parcourus en 3 s de marche, fusil sur le socket Rifle du MetaHuman, visée OK, 0 erreur. Mains écartées de 38,6 cm en visée (32,9 dans l'anim source) → recalage de la main gauche à faire.
    • Bug escalade (2026-11-05) : sur un bloc de 2 m le perso montait à 3,43 m.
      • Cause : les warps de traversée (FrontLedge…) utilisent l'os attach comme repère (WarpPointAnimProvider = Bone). Il n'était pas animé dans les séquences converties (ni chaîne ni pin dans le RTG) → resté à la racine.
      • Correction : piste attach recopiée image par image depuis les originaux de main dans les 70 séquences concernées (73 montages : Climb, Mantle, Vault, Hurdle, Catch, Bench) via AnimSequencerController.set_bone_track_keys.
      • Après modification d'anims, l'index interne du chooser CHT_TraversalMontages_Mover reste « annulé » jusqu'au redémarrage de l'éditeur.
      • Vérifié sur une map de test : mantle 1 m et 1,5 m, escalade 2 m et 2,4 m, le perso finit à la hauteur du bloc.
    • Restent pour le nettoyage : AC_VisualOverrideManager, BP_VisualOverride_MetaHuman, ABP_GenericRetarget, RTG_UEFN_to_MetaHuman_test, IK_MetaHuman_test, CVar DDCvar.VisualOverride, IA_NextVisualOverride.

Décisions (validées le 2026-10-31)

  • Assets convertis dans le dossier miroir Content/Characters/MH/… ; le contenu UEFN est supprimé à la fin.
  • SandboxCharacter_CMC est supprimé au nettoyage final (non converti).
  • Les 17 os manquants sont ajoutés au MetaHuman (SKM_test_BodyMesh + metahuman_base_skel).