Hi
I am trying to achieve something very simple, but the cryptic workings of Unreal’s reflection system makes the task rather difficult.
What I have:
- A custom K2_Node
- A C++ base class, called UMyScript
- A Blueprint BP_MyScript deriving from UMyScript containing said node
- A UPROPERTY called Config, of type TArray< FMyStruct >, which is defined in UMyScript
Need:
- Given a BP_MyScript that contains the node, read the value of the property Config, and its contents.
Why is this difficult?
You can easily get the Blueprint containing the node via GetTypedOuter, but it cannot be cast to UMyScript - presumably because BP_MyScript is a GENERATED class, which works differently than a C++ instance of UMyScript. I assume that because GetTypedOuter< UMyScript > fails – the last object in the chain is the Blueprint generated class.
So I am left with one choice, surely the generated class will have the reflected property. So there must be a way to read it via the Reflection system (FieldIterator? FindPropertyByName?). But the syntax and lack of documentation has made this very difficult. I made 3 attempts, here is the latest one:
// Assumption: The CDO of the generated class represents the blueprint asset I see and edit inside the editor
UObject* scriptCDO = nullptr;
FArrayProperty* configProp = nullptr;
if(UBlueprint* owningBP = GetTypedOuter<UBlueprint>())
{
if(owningBP->ParentClass->IsChildOf<UMyScript>())
{
scriptCDO = owningBP->GetBlueprintClass()->GetDefaultObject();
configProp = CastField<FArrayProperty>(owningBP->GeneratedClass->FindPropertyByName(TEXT("Config")));
}
}
// At this point, configProp is actually valid
// But I dont know how to use it...
int32 NumElements = configProp ->ArrayDim;
for(int32 i = 0; i < NumElements; i++)
{
// How do you use this? Does this return the entire array? Is it expecting my object instance as argument?
configProp ->GetPropertyValuePtr(scriptCDO );
// Same, how is this different? Is this to index into array properties? Will this return FMyStruct?
configProp ->GetPropertyValue_InContainer(scriptCDO, i);
}