98 lines
2.7 KiB
C++
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;
|
|
} |