添加背包配置资源的缩略图表

This commit is contained in:
997146918 2025-08-31 16:10:56 +08:00
parent a66065abae
commit f99367951a
4 changed files with 218 additions and 3 deletions

View File

@ -7,6 +7,8 @@
#include "AssetRegistry/AssetRegistryModule.h" #include "AssetRegistry/AssetRegistryModule.h"
#include "ProjectFish/DataAsset/BagShapeAsset.h" #include "ProjectFish/DataAsset/BagShapeAsset.h"
#include "../Public/Thumbnail/BagShapeAssetThumbnailRenderer.h" #include "../Public/Thumbnail/BagShapeAssetThumbnailRenderer.h"
#include "../Public/Thumbnail/BagConfigThumbnailRenderer.h"
#include "ProjectFish/DataAsset/BagConfigAsset.h"
#define LOCTEXT_NAMESPACE "FProjectFishEditorModule" #define LOCTEXT_NAMESPACE "FProjectFishEditorModule"
@ -72,6 +74,7 @@ void FProjectFishEditorModule::UnregisterAssetTypeActions()
void FProjectFishEditorModule::RegisterThumbnailRenderers() void FProjectFishEditorModule::RegisterThumbnailRenderers()
{ {
UThumbnailManager::Get().RegisterCustomRenderer(UBagShapeAsset::StaticClass(), UBagShapeAssetThumbnailRenderer::StaticClass()); UThumbnailManager::Get().RegisterCustomRenderer(UBagShapeAsset::StaticClass(), UBagShapeAssetThumbnailRenderer::StaticClass());
UThumbnailManager::Get().RegisterCustomRenderer(UBagConfigAsset::StaticClass(), UBagConfigThumbnailRenderer::StaticClass());
RefreshExistingAssetThumbnails(); RefreshExistingAssetThumbnails();
} }
@ -80,6 +83,7 @@ void FProjectFishEditorModule::UnregisterThumbnailRenderers()
if (UObjectInitialized()) if (UObjectInitialized())
{ {
UThumbnailManager::Get().UnregisterCustomRenderer(UBagShapeAsset::StaticClass()); UThumbnailManager::Get().UnregisterCustomRenderer(UBagShapeAsset::StaticClass());
UThumbnailManager::Get().UnregisterCustomRenderer(UBagConfigAsset::StaticClass());
} }
} }
@ -98,13 +102,13 @@ void FProjectFishEditorModule::RefreshExistingAssetThumbnails()
AssetRegistry.GetAssetsByClass(UBagShapeAsset::StaticClass()->GetClassPathName(), BagShapeAssetList); AssetRegistry.GetAssetsByClass(UBagShapeAsset::StaticClass()->GetClassPathName(), BagShapeAssetList);
// 查找所有BagClass资产 // 查找所有BagClass资产
TArray<FAssetData> BagClassAssetList; TArray<FAssetData> BagConfigAssetList;
//AssetRegistry.GetAssetsByClass(UBagClass::StaticClass()->GetClassPathName(), BagClassAssetList); AssetRegistry.GetAssetsByClass(UBagConfigAsset::StaticClass()->GetClassPathName(), BagConfigAssetList);
// 合并资产列表 // 合并资产列表
TArray<FAssetData> AllAssets; TArray<FAssetData> AllAssets;
AllAssets.Append(BagShapeAssetList); AllAssets.Append(BagShapeAssetList);
AllAssets.Append(BagClassAssetList); AllAssets.Append(BagConfigAssetList);
// 刷新每个资产的缩略图 // 刷新每个资产的缩略图
UThumbnailManager& ThumbnailManager = UThumbnailManager::Get(); UThumbnailManager& ThumbnailManager = UThumbnailManager::Get();

View File

@ -0,0 +1,179 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Thumbnail/BagConfigThumbnailRenderer.h"
#include "CanvasItem.h"
#include "CanvasTypes.h"
#include "ProjectFish/DataAsset/BagConfigAsset.h"
#include "ProjectFish/DataAsset/BagShapeAsset.h"
bool UBagConfigThumbnailRenderer::CanVisualizeAsset(UObject* Object)
{
return Cast<UBagConfigAsset>(Object) != nullptr;
}
void UBagConfigThumbnailRenderer::Draw(UObject* Object, int32 X, int32 Y, uint32 Width, uint32 Height,
FRenderTarget* RenderTarget, FCanvas* Canvas, bool bAdditionalViewFamily)
{
UBagConfigAsset* BagConfig= Cast<UBagConfigAsset>(Object);
if (!BagConfig || !Canvas)
{
return;
}
DrawBag(BagConfig, Canvas, X, Y, Width, Height);
}
void UBagConfigThumbnailRenderer::DrawBag(UBagConfigAsset* BagConfig, FCanvas* Canvas, int32 X, int32 Y,
uint32 Width, uint32 Height)
{
if (!BagConfig || !Canvas)
{
return;
}
// 检查是否有背包形状资源
if (!BagConfig->BagShapeAsset)
{
// 绘制错误状态
FCanvasBoxItem ErrorBox(FVector2D(X, Y), FVector2D(Width, Height));
ErrorBox.SetColor(FLinearColor(0.5f, 0.1f, 0.1f, 1.0f));
Canvas->DrawItem(ErrorBox);
return;
}
UBagShapeAsset* BagShapeAsset = BagConfig->BagShapeAsset;
// Clear the background
FCanvasBoxItem BackgroundBox(FVector2D(X, Y), FVector2D(Width, Height));
BackgroundBox.SetColor(FLinearColor(0.1f, 0.1f, 0.1f, 1.0f));
Canvas->DrawItem(BackgroundBox);
// Calculate the best fit scale with spacing for separators
float SeparatorWidth = 2.0f; // White separator width
float Scale = GetBestFitScale(BagShapeAsset->BagWidth, BagShapeAsset->BagHeight, Width, Height);
float CellSize = Scale - SeparatorWidth; // Reduce cell size to make room for separators
// Calculate starting position to center the grid (including separators)
float GridWidth = BagShapeAsset->BagWidth * Scale - SeparatorWidth;
float GridHeight = BagShapeAsset->BagHeight * Scale - SeparatorWidth;
float StartX = X + (Width - GridWidth) * 0.5f;
float StartY = Y + (Height - GridHeight) * 0.5f;
// Draw the bag slots (background) with separators
for (int32 GridY = 0; GridY < BagShapeAsset->BagHeight; GridY++)
{
for (int32 GridX = 0; GridX < BagShapeAsset->BagWidth; GridX++)
{
float CellStartX = StartX + GridX * Scale;
float CellStartY = StartY + GridY * Scale;
bool bIsActive = BagShapeAsset->IsSlotActive(GridX, GridY);
// Draw filled cell (smaller to leave space for separators)
FCanvasTileItem CellTile(FVector2D(CellStartX, CellStartY), FVector2D(CellSize, CellSize),
bIsActive ? FLinearColor(0.3f, 0.3f, 0.3f, 1.0f) : FLinearColor(0.15f, 0.15f, 0.15f, 1.0f));
CellTile.BlendMode = SE_BLEND_Opaque;
Canvas->DrawItem(CellTile);
}
}
// Draw white separators
// Vertical separators
for (int32 GridX = 1; GridX < BagShapeAsset->BagWidth; GridX++)
{
float SeparatorX = StartX + GridX * Scale - SeparatorWidth;
FCanvasTileItem VerticalSeparator(FVector2D(SeparatorX, StartY), FVector2D(SeparatorWidth, GridHeight), FLinearColor::White);
VerticalSeparator.BlendMode = SE_BLEND_Opaque;
Canvas->DrawItem(VerticalSeparator);
}
// Horizontal separators
for (int32 GridY = 1; GridY < BagShapeAsset->BagHeight; GridY++)
{
float SeparatorY = StartY + GridY * Scale - SeparatorWidth;
FCanvasTileItem HorizontalSeparator(FVector2D(StartX, SeparatorY), FVector2D(GridWidth, SeparatorWidth), FLinearColor::White);
HorizontalSeparator.BlendMode = SE_BLEND_Opaque;
Canvas->DrawItem(HorizontalSeparator);
}
// Draw skills on top
for (const FPlacedSkillInfo& PlacedSkill : BagConfig->PlacedSkills)
{
DrawSkill(PlacedSkill, Canvas, StartX, StartY, Scale, SeparatorWidth);
}
// Draw outer border
FCanvasBoxItem OuterBorder(FVector2D(StartX, StartY), FVector2D(GridWidth, GridHeight));
OuterBorder.SetColor(FLinearColor::White);
OuterBorder.LineThickness = 3.0f;
Canvas->DrawItem(OuterBorder);
}
float UBagConfigThumbnailRenderer::GetBestFitScale(int32 BagWidth, int32 BagHeight, uint32 CanvasWidth,
uint32 CanvasHeight) const
{
if (BagWidth == 0 || BagHeight == 0)
{
return 1.0f;
}
// Leave some padding
float PaddedWidth = CanvasWidth * 0.85f;
float PaddedHeight = CanvasHeight * 0.85f;
float ScaleX = PaddedWidth / BagWidth;
float ScaleY = PaddedHeight / BagHeight;
// Use the smaller scale to ensure everything fits
float Scale = FMath::Min(ScaleX, ScaleY);
// Ensure minimum cell size for visibility
Scale = FMath::Max(Scale, 3.0f);
return Scale;
}
void UBagConfigThumbnailRenderer::DrawSkill(const struct FPlacedSkillInfo& PlacedSkill, FCanvas* Canvas, float StartX,
float StartY, float Scale, float SeparatorWidth)
{
if (!PlacedSkill.SkillAsset)
{
return;
}
USkillAsset* SkillObject = PlacedSkill.SkillAsset;
float CellSize = Scale - SeparatorWidth;
float SkillStartX = StartX + PlacedSkill.PositionX * Scale;
float SkillStartY = StartY + PlacedSkill.PositionY * Scale;
float SkillWidth = GetSkillSizeValue(SkillObject->SkillSize).X * Scale - SeparatorWidth;
float SkillHeight = GetSkillSizeValue(SkillObject->SkillSize).Y * Scale - SeparatorWidth;
// Draw skill background
FCanvasTileItem SkillTile(FVector2D(SkillStartX, SkillStartY), FVector2D(SkillWidth, SkillHeight), FLinearColor::Blue);
SkillTile.BlendMode = SE_BLEND_Opaque;
Canvas->DrawItem(SkillTile);
// Draw skill border
FCanvasBoxItem SkillBorder(FVector2D(SkillStartX, SkillStartY), FVector2D(SkillWidth, SkillHeight));
SkillBorder.SetColor(FLinearColor::White);
SkillBorder.LineThickness = 2.0f;
Canvas->DrawItem(SkillBorder);
// Draw skill name (if there's enough space)
if (CellSize >= 12.0f && !SkillObject->SkillName.ToString().IsEmpty())
{
FString DisplayName = SkillObject->SkillName.ToString();
if (DisplayName.Len() > 8)
{
DisplayName = DisplayName.Left(6) + TEXT("..");
}
FCanvasTextItem TextItem(FVector2D(SkillStartX + 2, SkillStartY + 2), FText::FromString(DisplayName), GEngine->GetSmallFont(), FLinearColor::White);
TextItem.Scale = FVector2D(0.7f, 0.7f);
Canvas->DrawItem(TextItem);
}
}

View File

@ -0,0 +1,32 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "ThumbnailRendering/DefaultSizedThumbnailRenderer.h"
#include "BagConfigThumbnailRenderer.generated.h"
/**
*
*/
UCLASS()
class PROJECTFISHEDITOR_API UBagConfigThumbnailRenderer : public UDefaultSizedThumbnailRenderer
{
GENERATED_BODY()
public:
// UThumbnailRenderer interface
virtual bool CanVisualizeAsset(UObject* Object) override;
virtual void Draw(UObject* Object, int32 X, int32 Y, uint32 Width, uint32 Height, FRenderTarget* RenderTarget, FCanvas* Canvas, bool bAdditionalViewFamily) override;
private:
/** Draw the bag class with skills on canvas */
void DrawBag(class UBagConfigAsset* BagConfig, FCanvas* Canvas, int32 X, int32 Y, uint32 Width, uint32 Height);
/** Get the best fit scale for the bag class */
float GetBestFitScale(int32 BagWidth, int32 BagHeight, uint32 CanvasWidth, uint32 CanvasHeight) const;
/** Draw a skill at the specified position */
void DrawSkill(const struct FPlacedSkillInfo& PlacedSkill, FCanvas* Canvas, float StartX, float StartY, float Scale, float SeparatorWidth);
};