Let’s say, some object has a UStructProperty. We get it like this:
auto lStructProperty = FindFieldChecked<UStructProperty>(lClass, *lFieldName);
We can get a reference to the raw structure like this:
void * lStructure = lStructProperty->ContainerPtrToValuePtr<void>(aObject);
After that there must be a way to get info about a structure in this pointer, that is the big question of this thread:
UStruct lStruct = ????
Here is the complete code I’m trying to get working:
/*
* Get final path to a property from a path like "SubPropertyAtLEvel1.SubPropertyAtLEvel2.FinalPropertyName"
*/
bool UStrangeUtilities_RTTI::GetFinalPropertyPath(UObject * & aObject, FName & aPropertyName)
{
UClass* lClass = aObject->GetClass();
//bool lInnerStructFound;
bool lInnerClassFound;
do
{
FString lObjectName;
FString lFieldName;
/*
lInnerStructFound = aPropertyName.ToString().Split(".", &lObjectName, &lFieldName, ESearchCase::CaseSensitive);
if (lInnerStructFound)
{
auto lStructProperty = FindFieldChecked<UStructProperty>(lClass, *lObjectName);
if (lStructProperty != nullptr)
{
return false; //Error.
};
void * lStructure = lStructProperty->ContainerPtrToValuePtr<void>(aObject);
// Find inner struct?
UStruct lStruct = UStruct::StaticStruct();
lClass = aObject->GetClass();
aPropertyName = *lFieldName;
}
*/
lInnerClassFound = aPropertyName.ToString().Split(".", &lObjectName, &lFieldName, ESearchCase::CaseSensitive);
if (lInnerClassFound)
{
auto lObjectProperty = FindFieldChecked<UObjectProperty>(lClass, *lObjectName);
if (lObjectProperty != nullptr)
{
return false; // Error.
};
aObject = lObjectProperty->GetPropertyValue_InContainer(aObject, 0);
lClass = aObject->GetClass();
aPropertyName = *lFieldName;
}
} while (lInnerClassFound);
return true;
}
I’m testing it on this set of classes:
/**
* Dummy test class 1.
*/
UCLASS(BlueprintType)
class UAstraUtilities_UnitTests_TestClass1: public UObject
{
GENERATED_BODY()
public:
/**
* Dummy property 1.
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Astra")
FString StringProperty;
/**
* Dummy property 2.
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Astra")
float FloatProperty;
};
/**
* Dummy test structure 2.
*/
USTRUCT(BlueprintType)
struct FAstraUtilities_UnitTests_TestStruct2
{
GENERATED_BODY()
public:
/**
* Dummy property 1.
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Astra")
UAstraUtilities_UnitTests_TestClass1 * Property1;
/**
* Dummy constructor.
*/
FAstraUtilities_UnitTests_TestStruct2()
:
Property1(NewObject<UAstraUtilities_UnitTests_TestClass1>())
{
// Nothing here.
}
};
/**
* Dummy test class 3.
*/
UCLASS(BlueprintType)
class UAstraUtilities_UnitTests_TestClass3 : public UObject
{
GENERATED_BODY()
public:
/**
* Dummy property 1.
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Astra")
UAstraUtilities_UnitTests_TestClass1 * ObjectProperty1 = NewObject<UAstraUtilities_UnitTests_TestClass1>();
/**
* Dummy property 2.
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Astra")
FAstraUtilities_UnitTests_TestStruct2 StructProperty2;
};