Files
ProjectFGame/Docs/Plan_Conversion_MetaHuman.md
T
DodoandClaude Opus 5.5 0a75368317 Conversion MetaHuman phase 8 : suppression des redirecteurs
- 2100 redirecteurs supprimés (anciens chemins des animations UEFN et de
  la table miroir, qui pointaient vers Characters/MH) ; plus aucun asset
  ne les utilisait
- relevé de compilation avant/après identique : 465 Blueprints, 0 erreur
- override visuel, pion CMC et mannequin UEFN conservés pour plus tard

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

215 lines
19 KiB
Markdown

# 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`.
- **Phase 7 (2026-11-05)** — tests en PIE, pilotés par script (entrées Enhanced Input injectées, relevés à chaque frame) :
- **OK** :
- course 3,7 m/s, accroupi 1,7 m/s, sprint 5,85 m/s, saut en sprint, réception ;
- mantle 1 m / 1,5 m, escalade 2 m / 2,4 m (après correction de `attach`) ;
- prone à l'arrêt (`PSD_Dense_Prone_Idles`) ;
- fusil sur le socket `Rifle` du MetaHuman, main gauche à 5 cm du socket `LH_IK` (écart poignet-paume), identique en visée → recalage non nécessaire ;
- ragdoll physique sur `PHYS_test` (corps au sol, visage qui suit, hitbox de tête à 6 cm) ;
- portrait d'inventaire (silhouette complète dans `RT_CharacterView`) ;
- aucune nouvelle erreur au journal.
- **Problèmes trouvés, a priori antérieurs à la conversion** :
- **reptation en prone** : `ValidDatabases` = 0 pendant le déplacement → pose quasi debout. Le chooser `CHT_PoseSearchDatabases_Mover` signale depuis le 31/10 des liaisons introuvables (`Cover`, `Cover Direction`, `WantToSwinSpr`) ;
- le 2e appui sur crouch ne relève pas le perso (C partagé entre crouch et prone) ;
- `IA_TriggerRagdoll` (R) n'est pas géré par le pion Mover ;
- « Divide by zero » dans `AC_TraversalLogic` pendant les traversées.
- **Reptation corrigée** : dans `CHT_PoseSearchDatabases_Mover`, la ligne racine « Prone Moving » demandait `Stance = Stand` (`E_Stance::NewEnumerator0`) au lieu de `Prone` → passée à `NewEnumerator2` (via `ToolsetLibrary.set_object_properties` sur `ColumnsStructs`, seule différence à l'export T3D). En PIE : `PSD_Dense_Prone_Walk_Loops` en rampant, tête à ~40 cm.
- **Prone sur place corrigé** (se coucher sans bouger gardait l'idle debout) :
- chooser : lignes « Prone Idle » et « Prone Moving » en `Gait = MatchAny` (la gait ne passait à `PRONE` que ~4 s après la stance → aucune base valide entre-temps) ;
- `Get_MMInterruptMode` (ABP) : la branche GASP d'origine « (état de mouvement OU gait en mouvement OU **stance** changés) ET au sol » était débranchée ; rebranchée sur une 4e entrée du OR final (`BlueprintTools.add_node_pin` + `connect_pins`).
- Vérifié via `ToggleProne` : couché sur place (tête 40 cm), reptation 1,25 m/s, retour debout.
- Reste : la touche C (maintien) déclenche le prone de façon irrégulière, partagée avec crouch.
- **Non testés par script, à vérifier à la main** : cover AST (touche A), interactions (porte, placard, levier, pousser), nage, arc, mort.
- **Phase 8 (2026-11-05)** — nettoyage, périmètre choisi par l'utilisateur : **redirecteurs seulement**.
- Relevé avant : 465 Blueprints/AnimBP/widgets compilent (0 erreur, 2 avertissements).
- 2100 redirecteurs de conversion supprimés (anciens chemins UEFN → `Characters/MH`, plus la table miroir), 0 référenceur. Sauvegarde : `E:\projet\ProjectFv1_backup_mh_cleanup_2026-11-05\` (76,5 Mo).
- `delete_loaded_asset` dans l'éditeur : inutilisable à cette échelle (vérification des références à chaque asset, fichiers retirés en fin de lot → des heures). Fait éditeur fermé, directement sur le disque, après vérification sauvegarde + type `ObjectRedirector`. 60 dossiers vides retirés.
- Relevé après : identique (465, 0 erreur, mêmes 2 avertissements). PIE OK (corps, visage, déplacement, fusil).
- Avertissements antérieurs : « Reparenting the 'Face' component » (ajout du visage en phase 6, sans effet) ; `GM_Sandbox_Ragdoll` → `Systems/Blueprints/SandboxCharacter_Mover_Ragdoll` inexistant.
- **Reportés (décision utilisateur)** :
- système de visual override (`AC_VisualOverrideManager`, `BP_VisualOverride_MetaHuman`, `ABP_GenericRetarget`, RTG/IK de test, touche M, CVar) ;
- pion `SandboxCharacter_CMC` et son ABP (casts à retirer dans `BP_Simply_Door`, `BP_Moveble_Object`, `AC_Weapon`, `Gamemode_AGIS`, `BP_NotifyState_EarlyTransition`, GM/PC) ;
- mannequin UEFN (squelette, mesh, physique, matériaux) : des Control Rigs (`CR_UEFN_Mannequin_FullBodyIK` utilisé par l'ABP Mover, pieds, interaction, collision d'arme), `PCA_SandboxCharacter`, les bases (mesh de prévisualisation) et les retargeters Kimodo pointent encore dessus.
## 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`).