Feature requested through UDN see: https://udn.unrealengine.com/s/question/0D54z00009WAy1KCAT/can-you-let-soft-object-references-use-property-customization-widget?fromCase=1
A request has come in to be able to use customizations with soft references. Customer description:
Steps to reproduce:
Code:
1 -> In c++, create a new uclass (let's call it UMyClass) in a module or game sources.
2 -> In c++, create a property customization with IPropertyTypeCustomization for UMyClass properties,
(by example, replace the property handle's row widget by anything like just a label)
and register it in Editor module.
Usage:
3 -> In Editor open/create a blueprint then add a SoftObject reference variable for UMyClass
4 -> compile the BP.
Actual result
-> the customization in detail panel of the blueprint for the default value is not shown, instead, default uobject picker is shown.
Expected result:
If you create a hard reference variable in the BP for an UMyClass, the customization is correctly shown in the detail panel.
SoftObject reference should show same property customization.
They also left the fix for us to incorporate in PropertyEditorModule.cpp:
FPropertyTypeLayoutCallback FPropertyEditorModule::GetPropertyTypeCustomization(const FProperty* Property, const IPropertyHandle& PropertyHandle, const FCustomPropertyTypeLayoutMap& InstancedPropertyTypeLayoutMap) { if( Property ) { const FStructProperty* StructProperty = CastField<FStructProperty>(Property); bool bStructProperty = StructProperty && StructProperty->Struct; const bool bUserDefinedStruct = bStructProperty && StructProperty->Struct->IsA<UUserDefinedStruct>(); bStructProperty &= !bUserDefinedStruct; const UEnum* Enum = nullptr; if (const FByteProperty* ByteProperty = CastField<FByteProperty>(Property)) { Enum = ByteProperty->Enum; } else if (const FEnumProperty* EnumProperty = CastField<FEnumProperty>(Property)) { Enum = EnumProperty->GetEnum(); } if (Enum && Enum->IsA<UUserDefinedEnum>()) { Enum = nullptr; } const FObjectProperty* ObjectProperty = CastField<FObjectProperty>(Property); const bool bObjectProperty = ObjectProperty != NULL && ObjectProperty->PropertyClass != NULL; //~ Begin SoftObject support const FSoftObjectProperty* SoftObjectProperty = CastField<FSoftObjectProperty>(Property); const bool bSoftObjectProperty = SoftObjectProperty != NULL && SoftObjectProperty->PropertyClass != NULL; //~ End SoftObject support FName PropertyTypeName; if( bStructProperty ) { PropertyTypeName = StructProperty->Struct->GetFName(); } else if( Enum ) { PropertyTypeName = Enum->GetFName(); } else if ( bObjectProperty ) { UClass* PropertyClass = ObjectProperty->PropertyClass; while (PropertyClass) { const FPropertyTypeLayoutCallback& Callback = FindPropertyTypeLayoutCallback(PropertyClass->GetFName(), PropertyHandle, InstancedPropertyTypeLayoutMap); if (Callback.IsValid()) { return Callback; } PropertyClass = PropertyClass->GetSuperClass(); } } //~ Begin SoftObject support else if (bSoftObjectProperty) { UClass* PropertyClass = SoftObjectProperty->PropertyClass; while (PropertyClass) { const FPropertyTypeLayoutCallback& Callback = FindPropertyTypeLayoutCallback(PropertyClass->GetFName(), PropertyHandle, InstancedPropertyTypeLayoutMap); if (Callback.IsValid()) { return Callback; } PropertyClass = PropertyClass->GetSuperClass(); } } //~ End SoftObject support else { PropertyTypeName = Property->GetClass()->GetFName(); } return FindPropertyTypeLayoutCallback(PropertyTypeName, PropertyHandle, InstancedPropertyTypeLayoutMap); } return FPropertyTypeLayoutCallback(); }
There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-195390 in the post.