- SandboxCharacter_Mover : mesh SKM_test_BodyMesh animé par SandboxCharacter_Mover_ABP (mode AnimBP au lieu de Single Node), visage et MetaHumanComponentUE ajoutés, composant VisualOverride retiré - Inventory_Equipper : l'arme reste sur le socket du mesh du pion, plus de réattache au MetaHuman de l'override - validé en PIE : déplacement, fusil, visée, 0 erreur Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
177 lines
15 KiB
Markdown
177 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.
|
|
- 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`).
|