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

182 lines
15 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`.
## 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`).