By default, UObject-
derived UAssets open in the generic property editor. It looks like the following screenshot:
However, at times you may wish for custom widgets to allow editing of properties on your class. To facilitate this, Unreal supports Details Customization, which is the focus of this recipe.
MyCustomAssetDetailsCustomization.h
.#include "MyCustomAsset.h" #include "DetailLayoutBuilder.h" #include "IDetailCustomization.h" #include "IPropertyTypeCustomization.h"
class FMyCustomAssetDetailsCustomization : public IDetailCustomization { public: virtual void CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) override; void ColorPicked(FLinearColor SelectedColor); static TSharedRef<IDetailCustomization> FMyCustomAssetDetailsCustomization::MakeInstance() { return MakeShareable(new FMyCustomAssetDetailsCustomization); } TWeakObjectPtr<class UMyCustomAsset> MyAsset; };
CustomizeDetails
:void FMyCustomAssetDetailsCustomization::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) { const TArray< TWeakObjectPtr<UObject>>& SelectedObjects = DetailBuilder.GetDetailsView().GetSelectedObjects(); for (int32 ObjectIndex = 0; !MyAsset.IsValid() && ObjectIndex < SelectedObjects.Num(); ++ObjectIndex) { const TWeakObjectPtr<UObject>& CurrentObject = SelectedObjects[ObjectIndex]; if (CurrentObject.IsValid()) { MyAsset = Cast<UMyCustomAsset>(CurrentObject.Get()); } } DetailBuilder.EditCategory("CustomCategory", FText::GetEmpty(), ECategoryPriority::Important) .AddCustomRow(FText::GetEmpty()) [ SNew(SVerticalBox) + SVerticalBox::Slot() .VAlign(VAlign_Center) [ SNew(SColorPicker) .OnColorCommitted(this, &FMyCustomAssetDetailsCustomization::ColorPicked) ] ]; }
ColorPicked
:void FMyCustomAssetDetailsCustomization::ColorPicked(FLinearColor SelectedColor) { if (MyAsset.IsValid()) { MyAsset.Get()->ColorName = SelectedColor.ToFColor(false).ToHex(); } }
.cpp
file:#include "UE4CookbookEditor.h" #include "IDetailsView.h" #include "DetailLayoutBuilder.h" #include "DetailCategoryBuilder.h" #include "SColorPicker.h" #include "SBoxPanel.h" #include "DetailWidgetRow.h" #include "MyCustomAssetDetailsCustomization.h"
StartupModule
:FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor"); PropertyModule.RegisterCustomClassLayout(UMyCustomAsset::StaticClass()->GetFName(), FOnGetDetailCustomizationInstance::CreateStatic(&FMyCustomAssetDetailsCustomization::MakeInstance));
ShutdownModule
:FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor"); PropertyModule.UnregisterCustomClassLayout(UMyCustomAsset::StaticClass()->GetFName());
MyCustomAsset
via the content browser.IDetailCustomization
interface, which developers can inherit from when defining a class which customizes the way assets of a certain class are displayed.IDetailCustomization
uses to allow for this process to occur is the following:virtual void CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) override;
DetailBuilder
passed in as a parameter to get an array of all selected objects. The loop then scans those to ensure that at least one selected object is of the correct type.DetailBuilder
object. We create a new category for our details view by using the EditCategory
function.EditCategory
function is the name of the category we are going to manipulate.EditCategory
returns a reference to the category itself as CategoryBuilder
, allowing us to chain additional method calls onto an invocation of EditCategory
.AddCustomRow()
on CategoryBuilder
, which adds a new key-value pair to be displayed in the category.OnColorCommitted
delegate to our local ColorPicked
event handler. ColourPicked
. It has the following signature:void FMyCustomAssetDetailsCustomization::ColorPicked(FLinearColor SelectedColor)
ColorPicked
, we check to see if one of our selected assets was of the correct type, because if at least one selected asset was correct, then MyAsset
will be populated with a valid value. ColorName
property to the hex string value corresponding to the color selected by the user.18.221.208.183