Read nested structures from Blueprint in C++

Hello,

I’m trying to access a blueprint structure inside C++ code, so far I managed to read the type and name of the members.
The code is located inside an ActorComponent C++ class

Here is the actual code:


void UTest::BeginPlay()
{	
	Super::BeginPlay();


	FString structName = myStruct->GetName();
	UE_LOG(LogTemp, Warning, TEXT("Name of struct: %s"), *structName); //FOR LOG

	FField * child = myStruct->ChildProperties; //first element
	while (child != NULL) { //read all the members 
		FString fieldName = child->GetAuthoredName(); //name of the member
		FString typeName = child->GetClass()->GetName(); //type of the member
		UE_LOG(LogTemp, Warning, TEXT("- member : %s, type : %s"), *fieldName, *typeName); //FOR LOG

		child = child->Next; //go to the next member
	}
	
}

The myStruct variable is located inside the header:

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "Test.generated.h"


UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class MYPROJECT_API UTest : public UActorComponent
{
	GENERATED_BODY()
public:
	/* Struct */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Struct")
		UStruct* myStruct; //<-------------------- HERE
/* [...] */

So in order to use it I have to give it a struct in the editor.

For example here is the struct “myStruct” I created as blueprint structure:

image

And here is what my code is logging, you can see it can read the type and name of members

log1

But I’m struggling when it come to nested structs.
For example I added a custom struct called “RGB” inside the “myStruct”:

myStruct2

myStruct

RGBstruct

The RGB struct

When I run it, it reads myStruct (including the m_rgb) but does not display m_rgb content:

log2

I tried to use the GetInnerFields() function (FField::GetInnerFields | Unreal Engine Documentation) to get all the members but the array I pass as argument is always empty:

void UTest::BeginPlay()
{	
	Super::BeginPlay();

	//Parse the struct

	TArray< FField* > OutFields; //to read nested members

	FString structName = myStruct->GetName();
	UE_LOG(LogTemp, Warning, TEXT("Name of struct: %s"), *structName); //FOR LOG

	FField* child = myStruct->ChildProperties; //first element
	while (child != NULL) {
		FString fieldName = child->GetAuthoredName();
		FString typeName = child->GetClass()->GetName();
		UE_LOG(LogTemp, Warning, TEXT("- member : %s, type : %s"), *fieldName, *typeName); //FOR LOG

		child->GetInnerFields(OutFields); 
        //check if the member is a structure itself and if it is, parse the structure		
		if (OutFields.Num() > 0) {
			UE_LOG(LogTemp, Warning, TEXT("it's a struct!")); //### it never reach here and OutFields is always empty ###
		}
		child = child->Next;
	}
}

So my questions is : Is it possible to read the type and name of members in nested structures and if yes, how ?

1 Like

This kind of thing is really tough, but it can be done. First recommendation: don’t! Move your BP structs back to C++ if you can. I know that’s not always possible, but if it is for your project then do that instead to save yourself many, many headaches.

If you can’t then I’d recommend digging into the LevelSnapshots plugin in Engine>Plugins>VirtualProduction>LevelSnapshots. We had to do stuff like this for that project but it was a team effort so I couldn’t tell you exactly where to look. A good starting point might be LevelSnapshotsEditorCustomWidgetGenerator.cpp and LevelSnapshotsEditorResultsRow.cpp.

2 Likes

Thanks you for your reply, but unfortunately, I need to get an user structure created in blueprint, I will take a look at LevelSnapshot.

Bump, anyone here ?