From 9171347f2ebaf6bc94d6c6a03d8ab6f720372b0e Mon Sep 17 00:00:00 2001 From: 997146918 <997146918@qq.com> Date: Sat, 30 Aug 2025 19:55:46 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=83=8C=E5=8C=85=E5=BD=A2?= =?UTF-8?q?=E7=8A=B6=E8=B5=84=E6=BA=90=E5=9B=BE=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Private/ProjectFishEditor.cpp | 66 ++++++++++ .../BagShapeAssetThumbnailRenderer.cpp | 117 ++++++++++++++++++ .../Private/Widgets/BagShapeEditorWidget.cpp | 17 +++ .../Public/ProjectFishEditor.h | 7 +- .../BagShapeAssetThumbnailRenderer.h | 26 ++++ 5 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 ProjectFish/Source/ProjectFishEditor/Private/Thimbnail/BagShapeAssetThumbnailRenderer.cpp create mode 100644 ProjectFish/Source/ProjectFishEditor/Public/Thimbnail/BagShapeAssetThumbnailRenderer.h diff --git a/ProjectFish/Source/ProjectFishEditor/Private/ProjectFishEditor.cpp b/ProjectFish/Source/ProjectFishEditor/Private/ProjectFishEditor.cpp index 49ed01d..fcd7be8 100644 --- a/ProjectFish/Source/ProjectFishEditor/Private/ProjectFishEditor.cpp +++ b/ProjectFish/Source/ProjectFishEditor/Private/ProjectFishEditor.cpp @@ -3,6 +3,9 @@ #include "AssetTypeActions_Base.h" #include "DataTableRowSelectorCustomization.h" #include "AssetActions/BagShapeAssetTypeAction.h" +#include "AssetRegistry/AssetRegistryModule.h" +#include "ProjectFish/DataAsset/BagShapeAsset.h" +#include "Thimbnail/BagShapeAssetThumbnailRenderer.h" #define LOCTEXT_NAMESPACE "FProjectFishEditorModule" @@ -36,6 +39,9 @@ void FProjectFishEditorModule::RegisterAssetTypeActions() TSharedRef BagShapeAction = MakeShareable(new FBagShapeAssetTypeAction(BoxShapeAssetCategory)); AssetTools.RegisterAssetTypeActions(BagShapeAction); CreatedAssetTypeActions.Add(BagShapeAction); + + + RegisterThumbnailRenderers(); } void FProjectFishEditorModule::UnregisterAssetTypeActions() @@ -50,6 +56,66 @@ void FProjectFishEditorModule::UnregisterAssetTypeActions() } } CreatedAssetTypeActions.Empty(); + + UnregisterThumbnailRenderers(); +} + +void FProjectFishEditorModule::RegisterThumbnailRenderers() +{ + UThumbnailManager::Get().RegisterCustomRenderer(UBagShapeAsset::StaticClass(), UBagShapeAssetThumbnailRenderer::StaticClass()); + RefreshExistingAssetThumbnails(); +} + +void FProjectFishEditorModule::UnregisterThumbnailRenderers() +{ + if (UObjectInitialized()) + { + UThumbnailManager::Get().UnregisterCustomRenderer(UBagShapeAsset::StaticClass()); + } +} + +void FProjectFishEditorModule::RefreshExistingAssetThumbnails() +{ + // 延迟执行以确保所有模块都已加载 + FTSTicker::GetCoreTicker().AddTicker(FTickerDelegate::CreateLambda([](float DeltaTime) -> bool + { + if (FModuleManager::Get().IsModuleLoaded("AssetRegistry")) + { + FAssetRegistryModule& AssetRegistryModule = FModuleManager::GetModuleChecked("AssetRegistry"); + IAssetRegistry& AssetRegistry = AssetRegistryModule.Get(); + + // 查找所有BagShapeAsset资产 + TArray BagShapeAssetList; + AssetRegistry.GetAssetsByClass(UBagShapeAsset::StaticClass()->GetClassPathName(), BagShapeAssetList); + + // 查找所有BagClass资产 + TArray BagClassAssetList; + //AssetRegistry.GetAssetsByClass(UBagClass::StaticClass()->GetClassPathName(), BagClassAssetList); + + // 合并资产列表 + TArray AllAssets; + AllAssets.Append(BagShapeAssetList); + AllAssets.Append(BagClassAssetList); + + // 刷新每个资产的缩略图 + UThumbnailManager& ThumbnailManager = UThumbnailManager::Get(); + for (const FAssetData& AssetData : AllAssets) + { + if (UObject* Asset = AssetData.GetAsset()) + { + // 通知系统资源已修改 + if (GEditor) + { + GEditor->GetEditorSubsystem()->BroadcastAssetPostImport(nullptr, Asset); + } + + } + } + } + + // 只执行一次,返回false停止ticker + return false; + }), 1.0f); // 1秒延迟 } #undef LOCTEXT_NAMESPACE diff --git a/ProjectFish/Source/ProjectFishEditor/Private/Thimbnail/BagShapeAssetThumbnailRenderer.cpp b/ProjectFish/Source/ProjectFishEditor/Private/Thimbnail/BagShapeAssetThumbnailRenderer.cpp new file mode 100644 index 0000000..7bd2dce --- /dev/null +++ b/ProjectFish/Source/ProjectFishEditor/Private/Thimbnail/BagShapeAssetThumbnailRenderer.cpp @@ -0,0 +1,117 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "Thimbnail/BagShapeAssetThumbnailRenderer.h" + +#include "CanvasItem.h" +#include "CanvasTypes.h" +#include "ProjectFish/DataAsset/BagShapeAsset.h" + +bool UBagShapeAssetThumbnailRenderer::CanVisualizeAsset(UObject* Object) +{ + return Cast(Object) != nullptr; +} + +void UBagShapeAssetThumbnailRenderer::Draw(UObject* Object, int32 X, int32 Y, uint32 Width, uint32 Height, + FRenderTarget* RenderTarget, FCanvas* Canvas, bool bAdditionalViewFamily) +{ + UBagShapeAsset* BagShapeAsset = Cast(Object); + if (!BagShapeAsset || !Canvas) + { + return; + } + + DrawBagShape(BagShapeAsset, Canvas, X, Y, Width, Height); +} + +void UBagShapeAssetThumbnailRenderer::DrawBagShape(UBagShapeAsset* BagShapeAsset, FCanvas* Canvas, int32 X, int32 Y, + uint32 Width, uint32 Height) +{ + if (!BagShapeAsset || !Canvas) + { + return; + } + + // 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.2f, 0.8f, 0.2f, 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 outer border + // FCanvasBoxItem OuterBorder(FVector2D(StartX, StartY), FVector2D(GridWidth, GridHeight)); + // OuterBorder.SetColor(FLinearColor::White); + // OuterBorder.LineThickness = 5.0f; + // Canvas->DrawItem(OuterBorder); +} + +float UBagShapeAssetThumbnailRenderer::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.9f; + float PaddedHeight = CanvasHeight * 0.9f; + + 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, 4.0f); + + return Scale; +} diff --git a/ProjectFish/Source/ProjectFishEditor/Private/Widgets/BagShapeEditorWidget.cpp b/ProjectFish/Source/ProjectFishEditor/Private/Widgets/BagShapeEditorWidget.cpp index 9baba92..6c0c0cc 100644 --- a/ProjectFish/Source/ProjectFishEditor/Private/Widgets/BagShapeEditorWidget.cpp +++ b/ProjectFish/Source/ProjectFishEditor/Private/Widgets/BagShapeEditorWidget.cpp @@ -236,4 +236,21 @@ void SBagShapeEditorWidget::OnSlotClicked(int32 X, int32 Y) void SBagShapeEditorWidget::RefreshThumbnail() { + if (!BagShapeAsset.IsValid()) + { + return; + } + + // 强制资源重新生成缩略图的最可靠方法 + //BagShapeAsset->MarkPackageDirty(); + + // // 触发完整的PostEditChange流程 + // FPropertyChangedEvent PropertyChangedEvent(nullptr); + // BagShapeAsset->PostEditChangeProperty(PropertyChangedEvent); + // + // // 通知系统资源已修改 + if (GEditor) + { + GEditor->GetEditorSubsystem()->BroadcastAssetPostImport(nullptr, BagShapeAsset.Get()); + } } diff --git a/ProjectFish/Source/ProjectFishEditor/Public/ProjectFishEditor.h b/ProjectFish/Source/ProjectFishEditor/Public/ProjectFishEditor.h index 341484a..a8ab9b4 100644 --- a/ProjectFish/Source/ProjectFishEditor/Public/ProjectFishEditor.h +++ b/ProjectFish/Source/ProjectFishEditor/Public/ProjectFishEditor.h @@ -11,10 +11,15 @@ public: virtual void ShutdownModule() override; private: - //Bagshap 编辑器相关 + //资源 编辑器相关 void RegisterAssetTypeActions(); void UnregisterAssetTypeActions(); + //资源图标 + void RegisterThumbnailRenderers(); + void UnregisterThumbnailRenderers(); + + void RefreshExistingAssetThumbnails(); /** Asset type actions */ TArray> CreatedAssetTypeActions; }; diff --git a/ProjectFish/Source/ProjectFishEditor/Public/Thimbnail/BagShapeAssetThumbnailRenderer.h b/ProjectFish/Source/ProjectFishEditor/Public/Thimbnail/BagShapeAssetThumbnailRenderer.h new file mode 100644 index 0000000..aedd543 --- /dev/null +++ b/ProjectFish/Source/ProjectFishEditor/Public/Thimbnail/BagShapeAssetThumbnailRenderer.h @@ -0,0 +1,26 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "ThumbnailRendering/DefaultSizedThumbnailRenderer.h" +#include "BagShapeAssetThumbnailRenderer.generated.h" + +/** + * + */ +UCLASS() +class PROJECTFISHEDITOR_API UBagShapeAssetThumbnailRenderer : public UDefaultSizedThumbnailRenderer +{ + GENERATED_BODY() +public: + 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 shape on canvas */ + void DrawBagShape(class UBagShapeAsset* BagShapeAsset, FCanvas* Canvas, int32 X, int32 Y, uint32 Width, uint32 Height); + + /** Get the best fit scale for the bag shape */ + float GetBestFitScale(int32 BagWidth, int32 BagHeight, uint32 CanvasWidth, uint32 CanvasHeight) const; +};