Files
UnrealEngineUWP/Engine/Source/Editor/DetailCustomizations/Private/DecalComponentDetails.cpp
jeremy moore 64c8e2c5d8 Avoid issues where use can see default decal material without knowing why.
Problem is that when we select non-decal materials on a decal component, the renderer will drop back to default material which can be confusing for the user.
Three changes have been made:
* Filter the material selection list to decal only materials. Note that this requires us to iterate up the parent AssetData chain for material instances which is potentially slow. But testing on our largest asset registry, this was still very usable.
* Pop a toast when a decal component has a non-decal material. This tells the user about the issue, and gives hyperlink to edit the material. This is to surface the legacy case or the case where material's are changed after selection.
* Show a map check warning when a decal component has a non-decal material. This is another way to surface the legacy case.
#rb Jason.Nadro

[CL 32976874 by jeremy moore in ue5-main branch]
2024-04-15 17:13:00 -04:00

79 lines
2.4 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "DecalComponentDetails.h"
#include "AssetRegistry/AssetRegistryModule.h"
#include "DetailCategoryBuilder.h"
#include "DetailLayoutBuilder.h"
#include "DetailWidgetRow.h"
#include "Materials/MaterialInterface.h"
#include "Modules/ModuleManager.h"
#include "PropertyCustomizationHelpers.h"
#define LOCTEXT_NAMESPACE "DecalComponentDetails"
static TAutoConsoleVariable<bool> CVarDecalFilterMaterialList(
TEXT("r.Decal.FilterMaterialList"),
true,
TEXT("Enable filtering of material list in Decal Component details panel.")
);
TSharedRef<IDetailCustomization> FDecalComponentDetails::MakeInstance()
{
return MakeShareable( new FDecalComponentDetails);
}
void FDecalComponentDetails::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder)
{
TArray<TWeakObjectPtr<UObject>> ObjectsBeingCustomized;
DetailBuilder.GetObjectsBeingCustomized(ObjectsBeingCustomized);
if (ObjectsBeingCustomized.Num() > 1)
{
return;
}
// Filter only show decal materials.
TSharedRef<IPropertyHandle> PropertyHandle = DetailBuilder.GetProperty(TEXT("DecalMaterial"));
DetailBuilder.EditDefaultProperty(PropertyHandle)->CustomWidget()
.NameContent()
[
PropertyHandle->CreatePropertyNameWidget()
]
.ValueContent()
[
SNew(SObjectPropertyEntryBox)
.PropertyHandle(PropertyHandle)
.AllowedClass(UMaterialInterface::StaticClass())
.ThumbnailPool(DetailBuilder.GetThumbnailPool())
.OnShouldFilterAsset(FOnShouldFilterAsset::CreateStatic(&FDecalComponentDetails::ShouldFilterDecalMaterialAsset))
];
}
bool FDecalComponentDetails::ShouldFilterDecalMaterialAsset(FAssetData const& AssetData)
{
if (!CVarDecalFilterMaterialList.GetValueOnAnyThread())
{
return false;
}
FAssetRegistryModule& AssetRegistryModule = FModuleManager::Get().LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry"));
return !IsDecalMaterialAssetRecursive(AssetData, AssetRegistryModule.Get());
}
bool FDecalComponentDetails::IsDecalMaterialAssetRecursive(FAssetData const& AssetData, IAssetRegistry const& AssetRegistry)
{
FString DataStr;
if (AssetData.GetTagValue("Parent", DataStr))
{
FAssetData ParentAsset = AssetRegistry.GetAssetByObjectPath(FSoftObjectPath(*DataStr));
return IsDecalMaterialAssetRecursive(ParentAsset, AssetRegistry);
}
else if (AssetData.GetTagValue("MaterialDomain", DataStr))
{
return DataStr.Equals(TEXT("MD_DeferredDecal"));
}
return false;
}
#undef LOCTEXT_NAMESPACE