// © 2025 Naked People Team. All Rights Reserved. #include "ClothingVisualsComponent.h" #include "ClothingItemDefinition.h" #include "ClothingItemInstance.h" #include "ClothingManager.h" #include "Components/SkeletalMeshComponent.h" #include "Materials/MaterialInstance.h" UClothingVisualsComponent::UClothingVisualsComponent() { PrimaryComponentTick.bCanEverTick = false; } void UClothingVisualsComponent::Initialize(USkeletalMeshComponent* InBodyMesh, UClothingManager* InClothingManager) { BodyMesh = InBodyMesh; ClothingManager = InClothingManager; if (!ClothingManager) return; ClothingManager->OnClothingEquip.AddUniqueDynamic(this, &UClothingVisualsComponent::HandleClothingEquip); ClothingManager->OnClothingUnequip.AddUniqueDynamic(this, &UClothingVisualsComponent::HandleClothingUnequip); for (const UClothingItemInstance* Equipped : ClothingManager->GetEquippedClothing()) { Apply(Equipped); } } void UClothingVisualsComponent::Apply(const UClothingItemInstance* ClothingItemInstance) { if (!ClothingItemInstance) return; const UClothingItemDefinition* Definition = ClothingItemInstance->GetClothingItemDefinition(); if (!Definition) return; USkeletalMeshComponent* SlotMesh = GetOrCreateSlotMesh(Definition->SlotType); if (!SlotMesh) return; SlotMesh->SetSkeletalMesh(Definition->SkeletalMesh); if (Definition->UseLeaderPose) { SlotMesh->SetLeaderPoseComponent(BodyMesh); } for (const TPair& Material : Definition->Materials) { SlotMesh->SetMaterialByName(Material.Key, Material.Value); } } void UClothingVisualsComponent::ClearSlot(EClothingSlotType SlotType) { if (const TObjectPtr* Found = SlotMeshes.Find(SlotType)) { (*Found)->SetLeaderPoseComponent(nullptr); (*Found)->SetSkeletalMesh(nullptr); } } void UClothingVisualsComponent::HandleClothingEquip(UClothingItemInstance* ClothingItemInstance) { Apply(ClothingItemInstance); } void UClothingVisualsComponent::HandleClothingUnequip(UClothingItemInstance* ClothingItemInstance) { if (ClothingItemInstance && ClothingItemInstance->GetClothingItemDefinition()) { ClearSlot(ClothingItemInstance->GetClothingItemDefinition()->SlotType); } } USkeletalMeshComponent* UClothingVisualsComponent::GetOrCreateSlotMesh(EClothingSlotType SlotType) { if (const TObjectPtr* Found = SlotMeshes.Find(SlotType)) { return *Found; } if (!BodyMesh) return nullptr; const FName ComponentName = *FString::Printf(TEXT("ClothingSlotMesh_%d"), static_cast(SlotType)); USkeletalMeshComponent* SlotMesh = NewObject(GetOwner(), ComponentName); SlotMesh->SetupAttachment(BodyMesh); SlotMesh->RegisterComponent(); SlotMeshes.Add(SlotType, SlotMesh); return SlotMesh; }