Protocole rejoue de bout en bout sur Pocolov 17 : resultat identique. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
10 KiB
13. Protocole de conversion d'une coiffure
Ce protocole décrit comment ajouter au jeu une coiffure livrée en maillage statique (FBX de Fab ou d'ailleurs),
sans modifier aucun Blueprint. Il a été établi sur Pocolov Hair 17 (lot O7e, 11_Audit_Optimisation.md §16.8) puis
rejoué de bout en bout avec les outils ci-dessous : résultat identique au millimètre.
Durée : environ 30 minutes pour une coiffure, contrôles en jeu compris.
1. Ce que le jeu attend d'une coiffure
| Exigence | Raison |
|---|---|
SkeletalMesh dont les os portent les noms Genesis 8 (hip, pelvis… neckUpper, head) |
Person fait suivre la coiffure au corps par SetLeaderPoseComponent, qui associe les os par leur nom |
| Placée autour de la tête de Bridget, dans la pose de référence | les sommets sont liés à l'os head ; une coiffure mal placée flotte ou traverse le crâne |
Matériaux enfants de /Game/Heavy/Daz/Bridget/Hairs/DazHair |
le jeu règle la couleur et l'épaisseur par les paramètres HairColor et HairThickness |
Déclarée dans un fichier Modules/<module>/**/*.lphair |
la liste des coiffures du jeu est construite depuis ces fichiers (lots H1, H2) ; un maillage non déclaré n'est jamais utilisé |
| Nom d'objet unique | les personnages désignent leur coiffure par ce nom (HAIR Hairstyle: <nom> dans les .lpcharacter) |
Coiffures exclues : les « grooms » MetaHuman (liés à la tête MetaHuman ; plugin HairStrands limité à l'éditeur
depuis O1). Une coiffure déjà riggée Genesis 8 (export Daz) n'a pas besoin des étapes 2 et 3 : l'importer en
SkeletalMesh et passer à l'étape 4.
2. Outils
| Outil | Rôle |
|---|---|
Tools/HairImportFbx.py |
import du FBX en maillages statiques séparés, dans un dossier de travail ; affiche tailles et emplacements de matériaux |
commandlet LPHairFromStaticMesh (Source/LifePlayEditorTools) |
ajuste la coiffure sur la tête de Bridget et la convertit en SkeletalMesh Genesis 8 |
Tools/HairMaterials.py |
importe les textures, crée les matériaux <Nom>_Cap et <Nom>_Strands, les affecte, contrôle les dépendances |
Tools/BuildCollections.py |
range la coiffure dans la collection LifePlay_Cheveux de l'éditeur |
option de jeu -LPVerifyHairstyles |
journalise la construction de la liste des coiffures |
Variables utilisées ci-dessous (PowerShell) :
$UE = 'D:\Game\Launcher\Engine\UE_5.5\Engine\Binaries\Win64\UnrealEditor-Cmd.exe'
$P = 'D:\Game\LifePlay-master 5.5\LifePlay.uproject'
$T = 'D:/Game/LifePlay-master 5.5/Tools'
$W = 'D:/Game/LifePlay_Backup_5.5/<lot>/src' # sources de travail, chemins SANS espaces
3. Étapes
Étape 0 : préparation
- Vérifier la licence du produit (page Fab : « License terms »). CC BY impose une attribution ; noter auteur, titre, lien.
- Télécharger l'archive (accord de l'utilisateur), la copier dans
D:\Game\LifePlay_Backup_5.5\<lot>\. - Extraire ; repérer le FBX et les textures. Copier dans
$Wsous des noms sans espaces (les arguments des scripts Python sont séparés par des espaces) :hair.fbx,diffuse.png,strands_opacity.jpg… - Identifier les textures en les ouvrant :
- couleur des mèches : de préférence grise (elle est teintée par
HairColor) ; - masque des mèches : blanc = visible, noir = transparent, en bandes verticales ;
- masque de la calotte (lisière) : facultatif, voir étape 4.
- couleur des mèches : de préférence grise (elle est teintée par
- Tag git
<lot>-avant. Choisir le nom de la coiffure (unique, sans espace, ex.Pocolov17) et son dossier :/Game/Heavy/New5/Hairs/(hors des dossiers à chemin fixe,08_Guide_Developpeur.md§2.1).
Étape 1 : import
& $UE $P -run=pythonscript "-script=$T/HairImportFbx.py fbx=$W/hair.fbx dest=/Game/Heavy/New5/Hairs/_Work" -unattended -nopause -nosplash
Lire les lignes HAIRIMPORT : repérer le maillage de la coiffure et la tête de référence souvent livrée avec
(ex. Pocolov : Hair_17, 8 250 triangles, emplacements Hair_Base, Hair_01 ; Head, 21 262 triangles). Noter
quel emplacement est la calotte (ici Hair_Base). Sans tête de référence, voir §5.
Étape 2 : ajustement et conversion
Essai à blanc d'abord :
& $UE $P -run=LPHairFromStaticMesh '-Static=/Game/Heavy/New5/Hairs/_Work/Hair_17' '-FitHead=/Game/Heavy/New5/Hairs/_Work/Head' '-Out=/Game/Heavy/New5/Hairs/<Nom>' -DryRun -unattended -nopause -nosplash
Contrôler les lignes LogLPHairFromStatic :
| Ligne | Attendu |
|---|---|
Tete du corps |
Bridget : haut du crâne ≈ 15 × 20 cm |
Tete de reference |
haut du crâne du même ordre |
Ajustement : echelle |
entre 0,8 et 1,5 sur chaque axe ; un écart fort entre X et Y signale une tête de référence atypique |
Os 'head' |
correction aucune (squelette cible identique au corps) |
Coiffure placee |
largeur ≈ 25 à 32 cm (Flora : 31 cm), sommet ≈ 181-183 cm |
Puis sans -DryRun. La commandlet refuse d'écraser un asset existant : pour refaire, déplacer d'abord <Nom> et
<Nom>_Skeleton vers la sauvegarde.
Paramètres de retouche (après un premier contrôle en jeu) : -OffsetZ= (cm, monter/descendre), -OffsetY= (cm,
avancer/reculer), -Scale= (facteur global), -Margin= (défaut 1,05 : écart calotte/cuir chevelu), -Cranium= (défaut
0,3 : hauteur mesurée sous le sommet, en fraction de la profondeur de la tête), -Uniform (même échelle sur X et Y).
Étape 3 : textures et matériaux
& $UE $P -run=pythonscript "-script=$T/HairMaterials.py mesh=/Game/Heavy/New5/Hairs/<Nom> diffuse=$W/diffuse.png strands_opacity=$W/strands_opacity.jpg cap_opacity=white cap=Hair_Base thicken=1" -unattended -nopause -nosplash
cap=: emplacements de la calotte (séparés par des virgules) ; tous les autres reçoivent le matériau des mèches.cap_opacity=white: calotte opaque (recommandé : une lisière découpée laisse voir le crâne entre les mèches) ; sinon le fichier du masque de la calotte.thicken=: épaississement du masque des mèches. 1 pour un masque large (cartes de mèches, Pocolov) ; 10 pour un masque de mèches fines (coiffures Daz). Une valeur trop forte donne des cartes opaques.
Contrôle : la dernière ligne HAIRMAT dependances … -> OK (la coiffure ne dépend que de son squelette et de ses deux
matériaux).
Étape 4 : nettoyage
Déplacer Content/Heavy/New5/Hairs/_Work vers D:\Game\LifePlay_Backup_5.5\<lot>\ (il ne doit pas être cuit dans le
jeu). Ne rien supprimer sans copie.
Étape 5 : déclaration
Fichier Content/Modules/<module>/Hairstyles/<nom>.lphair (module existant, ex. lp_Revival, ou module du mod) :
// <Titre> - <auteur> - licence <licence>
// Source : <lien>
// Modifications : rattachee au squelette Genesis 8 (os head), ajustee a la tete de Bridget, materiaux DazHair.
HAIRSTYLE: /Game/Heavy/New5/Hairs/<Nom>.<Nom>
SEX: F
DAZ: true
Licence à attribution : ajouter la même mention dans Licenses/Free_3D_Models_Credits.txt.
Étape 6 : collections, build, contrôle du journal
& $UE $P -run=pythonscript "-script=$T/BuildCollections.py" -unattended -nopause -nosplash
Build Development (09_Commandes_Utiles.md §2) dans un nouveau dossier d'archive (la mise en place avec -iterate
ne retire pas les fichiers supprimés). Lancer le jeu ; le journal doit contenir :
LogLifePlay: Coiffures : <Nom> ajoutee (index N, F, module <module>)
Étape 7 : contrôle en jeu (utilisateur)
| # | Contrôle | Défaut typique → correction |
|---|---|---|
| 1 | Création de personnage du bon sexe : la coiffure est en fin de liste | absente : chemin du .lphair, module désactivé, journal |
| 2 | De face : le crâne est couvert | zones chauves, coiffure étroite : vérifier l'ajustement (§4), -Scale, -Margin |
| 3 | De profil : rien ne traverse le crâne, l'oreille, les épaules ; pas de trou au-dessus de l'oreille | trous : cap_opacity=white ; trop haute/basse : -OffsetZ ; trop en avant/arrière : -OffsetY |
| 4 | Couleur et épaisseur réglables dans le menu | sans effet : matériau non DazHair |
| 5 | Mouvement (marche, animation) : la coiffure suit la tête | décalée : os head absent ou correction de pose non nulle |
| 6 | Nouvelle partie (liste des villes) et Continue | — |
Puis : entrée CHG dans Journal_Modifications.md, commit, tags <lot>-apres / <lot>-valide.
4. Pièges rencontrés (O7e)
| Piège | Effet | Règle |
|---|---|---|
| Ajuster sur la tête entière | la tête Pocolov a des oreilles très larges (24,4 cm) : coiffure rétrécie à 74 %, enfoncée dans le crâne | ajuster sur le haut du crâne (option -Cranium, par défaut) |
Thicken des coiffures Daz (10) sur un masque large |
mèches en cartes noires opaques | thicken=1 pour les cartes de mèches |
| Lisière découpée de la calotte | crâne visible au-dessus de l'oreille | cap_opacity=white |
| Affectation des matériaux en Python | save_loaded_asset ne sauve que les assets « modifiés » ; une affectation par propriété ne les marque pas |
sauvegarder avec only_if_is_dirty=False (fait par HairMaterials.py) |
| Matériaux importés du FBX | souvent sans texture reliée | ne pas importer les matériaux (HairImportFbx.py) ; recréer avec HairMaterials.py |
| Comparer des noms d'assets | soldier et Soldier désignent le même asset |
comparaisons insensibles à la casse |
5. Cas particuliers
- Pas de tête de référence dans le FBX : utiliser la coiffure elle-même comme
-FitHead(son haut est la calotte), avec-Margin=1.0, puis corriger en jeu avec-Scaleet-OffsetZ. - Coiffure masculine :
SEX: Mdans le.lphair(le menu du personnage masculin la propose). - Morphs de forme : non générés (la coiffure ne suit pas les morphs du visage). Un morph existant de la coiffure peut
être déclaré avec
FIT_MORPH: <morph> <valeur>. - Mèches animées : non gérées (coiffure rigide sur la tête).
- Coiffure apportée par un mod sans recompiler le jeu : impossible aujourd'hui (le maillage doit être cuit avec le jeu) ; étape H3 prévue.
6. Retour arrière
Retirer le fichier .lphair suffit à retirer la coiffure du jeu. Pour retirer aussi les assets : déplacer
Content/Heavy/New5/Hairs/<Nom>* vers la sauvegarde, régénérer les collections, reconstruire.