Description

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();
    } 

 

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-195390 in the post.

0
Login to Vote

Unresolved
CreatedSep 14, 2023
UpdatedSep 14, 2023