Refactor clothing visuals
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
// © 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;
|
||||
}
|
||||
Reference in New Issue
Block a user