From e8e128457a772c9f240b7fa16dbf60afd2aa84b6 Mon Sep 17 00:00:00 2001 From: Mathew Date: Sat, 8 Aug 2026 20:02:02 +0200 Subject: [PATCH] (Fix) Vider les materiaux surcharges au changement de mesh Passer du corps A au corps B donnait une silhouette feminine peinte avec la peau et les abdominaux du modele masculin. OverrideMaterials appartient au COMPOSANT et pas au mesh : SetSkeletalMeshAsset remplace l'asset sans y toucher, donc le MID derive de MI_BodyA_a restait colle a l'element 0. Le symptome trompe, parce que le mesh, lui, avait bien change -- seule sa peau ne suivait pas. SetPartMesh() vide les overrides avant d'assigner, et rend la main sans rien faire quand le mesh est deja le bon : un changement de couleur seul continue ainsi de reutiliser les MID en place au lieu de tout reconstruire. Vaut pour toutes les pieces, pas seulement le corps -- changer de tete ou de coiffure donnait le meme symptome. Co-Authored-By: Claude Opus 5 (1M context) --- .../Private/CharacterAppearanceComponent.cpp | 28 ++++++++++++++++--- .../Public/CharacterAppearanceComponent.h | 9 ++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/Source/Survival_projet/Private/CharacterAppearanceComponent.cpp b/Source/Survival_projet/Private/CharacterAppearanceComponent.cpp index 606fc40..cb3203a 100644 --- a/Source/Survival_projet/Private/CharacterAppearanceComponent.cpp +++ b/Source/Survival_projet/Private/CharacterAppearanceComponent.cpp @@ -246,7 +246,7 @@ void UCharacterAppearanceComponent::RebuildMeshes(const FCharacterBodySet& BodyS if (BodySet.BodyMeshes.Num() > 0 && BodySet.BodyMeshes[0]) { - TargetMesh->SetSkeletalMeshAsset(BodySet.BodyMeshes[0]); + SetPartMesh(TargetMesh, BodySet.BodyMeshes[0]); } if (BodySet.AnimClass) @@ -267,7 +267,7 @@ void UCharacterAppearanceComponent::RebuildMeshes(const FCharacterBodySet& BodyS if (USkeletalMeshComponent* Segment = ExtraBodyComponents[i]) { - Segment->SetSkeletalMeshAsset(BodySet.BodyMeshes[i + 1]); + SetPartMesh(Segment, BodySet.BodyMeshes[i + 1]); } } @@ -278,7 +278,7 @@ void UCharacterAppearanceComponent::RebuildMeshes(const FCharacterBodySet& BodyS { if (USkeletalMeshComponent* Segment = ExtraBodyComponents[i]) { - Segment->SetSkeletalMeshAsset(nullptr); + SetPartMesh(Segment, nullptr); } } @@ -305,7 +305,7 @@ void UCharacterAppearanceComponent::RebuildMeshes(const FCharacterBodySet& BodyS if (USkeletalMeshComponent* PartComponent = EnsurePartComponent(Category)) { - PartComponent->SetSkeletalMeshAsset(Mesh); + SetPartMesh(PartComponent, Mesh); } }; @@ -432,6 +432,26 @@ void UCharacterAppearanceComponent::ApplyColors(const FCharacterBodySet& BodySet } } +void UCharacterAppearanceComponent::SetPartMesh(USkeletalMeshComponent* MeshComponent, USkeletalMesh* NewMesh) +{ + if (!MeshComponent || MeshComponent->GetSkeletalMeshAsset() == NewMesh) + { + // Rien a faire, et surtout : on ne jette pas les MID en place pour + // rien. ApplyColors les reutilise, c'est ce qui rend le changement de + // couleur seul aussi bon marche. + return; + } + + // LE point du montage a ne pas oublier : les materiaux surcharges d'un + // composant vivent dans OverrideMaterials, un tableau qui lui appartient et + // que changer de mesh ne touche PAS. Sans ce vidage, passer du corps A au + // corps B garde le MID derive de MI_BodyA_a sur l'element 0 -- on obtient + // une silhouette feminine peinte avec la peau et les abdominaux du modele + // masculin. Le symptome trompe, parce que le mesh, lui, a bien change. + MeshComponent->EmptyOverrideMaterials(); + MeshComponent->SetSkeletalMeshAsset(NewMesh); +} + void UCharacterAppearanceComponent::TintAllElements(USkeletalMeshComponent* MeshComponent, FName Parameter, const FLinearColor& Color) { if (!MeshComponent || Parameter.IsNone() || !MeshComponent->GetSkeletalMeshAsset()) diff --git a/Source/Survival_projet/Public/CharacterAppearanceComponent.h b/Source/Survival_projet/Public/CharacterAppearanceComponent.h index 4eb556f..b646c42 100644 --- a/Source/Survival_projet/Public/CharacterAppearanceComponent.h +++ b/Source/Survival_projet/Public/CharacterAppearanceComponent.h @@ -133,6 +133,15 @@ private: void ApplyColors(const FCharacterBodySet& BodySet); /** Pose un parametre vectoriel sur TOUS les elements d'un mesh. */ + /** + * Assigne un mesh a un composant en vidant d'abord ses materiaux surcharges. + * + * Indispensable : OverrideMaterials appartient au COMPOSANT, pas au mesh, et + * survit donc a un changement d'asset. Sans ce vidage, le corps B garderait + * la peau du corps A. + */ + static void SetPartMesh(USkeletalMeshComponent* MeshComponent, USkeletalMesh* NewMesh); + static void TintAllElements(USkeletalMeshComponent* MeshComponent, FName Parameter, const FLinearColor& Color); /** Le mesh porteur, leader de tous les autres. */