Use BP defined structs and Enums in C++

Hi all,

Is it possible to access the custom structs and enums created in BPs in C++ ?

Best,
darkZ

Well I have a very complex BP where this custom struct is used a lot. I am just trying to save work by using the custom struct from BP in C++ code as well since I need to access the struct in code too. I suspected it wouldn’t be possible but I wanted to hear opinion of someone working on the engine code if possible.

#Yes You Can

You can access an enum created in BP by using the UEnum class

To get that Enum, which only exists in BP classes, you have to pass the AActor / UObject that has your Enum instance as a variable through this function which I wrote

//Get BP Enum
	static FORCEINLINE UEnum* GetBPEnum( UObject* Obj, const FName& Name, uint8& Value)
	{
		Value = 255; //invalid
		
		if(!Obj)			                return NULL;
          if(!Obj->IsValidLowLevel())	return NULL;
		if(Name == NAME_None) 	return NULL;
		//~~~~~~~~~~~~~~~
		
		UByteProperty* ByteProp = FindField<UByteProperty>(Obj->GetClass(), Name);
		if(ByteProp != NULL)
		{
			void * ValuePtr = ByteProp->ContainerPtrToValuePtr<void>(Obj);
			Value = ByteProp->GetUnsignedIntPropertyValue(ValuePtr);
			return ByteProp->GetIntPropertyEnum();
		}
		
		return NULL;
	}

For testing you can remove the word static and stick the above in some C++ Class of your choosing.

The FName is the name of the variable as you named the variable in Blueprints

so the type is your enum, the FName is the actual name you gave the variable!

the UObject you pass in can be an actor, it needs to be the actual instance of your BP class which has the enum you want to access.

To get the visual display name in C++ for debugging / logging, you can use this code:

//Works even in shipping builds!
FString GetVictoryEnumAsString(EVictoryEnum::Type EnumValue)
{
  const UEnum* EnumPtr = FindObject<UEnum>(ANY_PACKAGE, TEXT("EVictoryEnum"), true);
  if(!EnumPtr) return "";
 
  return EnumPtr->GetEnumName(EnumValue); 
}

#Example Usage

uint8 ValueFound = 255;
UEnum* TheEnum = GetBPEnum(MyActor,FName("ItemType"),ValueFound);
if(TheEnum && ValueFound != 255)
{
	UE_LOG(YourLog,Warning,TEXT("Item saved to hard disk ~ ", TheEnum->GetEnumName(ValueFound)); 
}

:slight_smile:

Rama

PS: Many special thanks to Shadow River for being awesome, looks like he’s answered more questions than me now!

Seems like this would work. Many thanks I will test it out. For now I will mark this as answered !