How to compare a property handle on one object a property on another object?

I am attempting to make a customization for a particular blueprint class that checks each property within the class and determines how many subclasses for the blueprint have the same value or a different value. For each property I have a TSharedRef<IPropertyHandle> propertyHandle and a pointer to the original UMyBlueprintAsset* originalAsset. I am using the global UObject::GetDerivedClasses function to get all derived objects, then accessing the CDO of each class to acquire UMyBlueprintAsset* childAsset

At first I’ve had success using propertyHandle->GetProperty()->GetValue_InContainer(childAsset, localPointer) to get a void pointer to the raw value and compare if the original and child properties are identical. However, we have found that if the property in question is a struct with the meta tag ShowOnlyInnerProperties, this implementation breaks. The propertyHandle lists the correct structProperty->innerProperty in its description, but getting the property pointer from the handle returns the property for just the struct and not UMyBlueprintAsset, causing a crash when attempting to get the value from childAsset.

How can I best work with a propertyHandle that’s interacting with the ShowOnlyInnerProperties tag? How can I retrieve the property value properly from a child asset? Is there some context I’m missing?

Hi David,

I’m not too familiar with ShowOnlyInnerProperties but I believe that if the property encapsulated by the handle is referring to the inner struct, you will not be able to use GetValue_InContainer with the asset in order to get to it.

Instead, you’ll probably need to first get the offset from the parent first:

void* ChildAddressToUse = childAsset;
void* OriginalAddressToUse = origAsset;
if (TSharedPtr<IPropertyHandle> ParentHandle = PropertyHandle->GetParentHandle())
{
    ChildAddressToUse = ParentHandle->GetProperty()->ContainerPtrToValuePtr<void>(ChildAddressToUse);
    OriginalAddressToUse = ParentHandle->GetProperty()->ContainerPtrToValuePtr<void>(OriginalAddressToUse);
    PropertyHandle = ParentHandle;
}
 
// Compare
bool bIdenticalProps = PropertyHandle->GetProperty()->Identical(OriginalAddress, ChildAddress);

You might have to do this in a loop if you have multiple outers - walk the outer chain and build up an array, then traverse the array backwards and continually offset them starting from your asset pointers.

Let me know if this works,

Steve