Files
Naked-Desire/Source/NakedDesire/Clothing/ClothingVisualsComponent.cpp
T
2026-06-03 15:16:46 +03:00

98 lines
2.7 KiB
C++

// © 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<FName, UMaterialInstance*>& Material : Definition->Materials)
{
SlotMesh->SetMaterialByName(Material.Key, Material.Value);
}
}
void UClothingVisualsComponent::ClearSlot(EClothingSlotType SlotType)
{
if (const TObjectPtr<USkeletalMeshComponent>* 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<USkeletalMeshComponent>* Found = SlotMeshes.Find(SlotType))
{
return *Found;
}
if (!BodyMesh)
return nullptr;
const FName ComponentName = *FString::Printf(TEXT("ClothingSlotMesh_%d"), static_cast<int32>(SlotType));
USkeletalMeshComponent* SlotMesh = NewObject<USkeletalMeshComponent>(GetOwner(), ComponentName);
SlotMesh->SetupAttachment(BodyMesh);
SlotMesh->RegisterComponent();
SlotMeshes.Add(SlotType, SlotMesh);
return SlotMesh;
}