Allow a BP to access a C++ defined reference

Edit: The Title should probably be "Allow a BP to access a C++ defined reference/pointer from a Parent Class."

I’m fairly new to C++ and UE4, so please don’t bite >.<

I declared a reference to a custom struct, for querying data in a datatable, in a Character Class. That reference works fine for passing that information around in C++, however now I would like to access either that reference or that data in a BP of that character. (so that I can populate an attached widget with data, a widget created using BP’s)

Ideally, I would like to avoid de-referencing the data into the character, have I missed something?

My first thought was to UPROPERTY the reference, and unsurprisingly, that didn’t work, especially after looking @ the docs.

Trying to google this specifically gives a lot of irrelevant results, for something that might have a very simple implementation.

tldr; I want to make a get node in BP that contains a reference to a specific dataset of my datatable.

Hi Raxis,

You have created a C++ struct, with some public members, and you wish to access those members inside the BPs from one of your instances of the struct?

Check out this forum posting and see if it answers your question: https://forums.unrealengine.com/archive/index.php/t-69341.html

Basically your struct needs this before declaring:
UCLASS(BlueprintType)

and each of the members you wish to expose need the UPROPERTY(BlueprintReadWrite) as well. Also you need the “GENERATED_BODY()” first in the struct I believe.

If everything is working, in your blueprint, you drag the instanced struct into the BP and look for the method you want to call, and it should show a “get/set” method (since this is “BlueprintReadWrite”).

Let me know if that helps

The method outlined in that thread is pretty much what I’ve already done.

I know it works because I can freely create structs in my BP’s of my custom type.

The problem is that I defined a struct reference in my class, and I want to access that struct reference from within BP.

As it stands, the class only has access to that reference that I can freely use in C++, but I’m unsure how I can expose that reference to my BP version of that class.

by “expose that reference to my BP version of that class” I mean, expose it to the editor, so I can use it.

Does following not work?

UPROPERTY(BlueprintReadWrite,EditAnywhere)
FYourCustomStruct YourVariable;

Hmm, okay. So if you define a struct inside a class, then create a blueprint inheriting from that class, you can access the struct references within that class via the “Variables” tab under the My Blueprint info the classes blueprint editor.

For example, I tried this with one of my existing classes. I created a struct called “Frar”, with a “int myTest” veriable in it. I then declared an instance of that struct as a member variable within a class called “URayBox”. See below:

Then, I created a blueprint inheriting from the class “URayBox”, called “PhysicalRayboxBP” (names are meaningless here, just what I had laying around when trying this out). On the left, under “My Blueprint”, under variables in the “Ray Box” category, I see my struct instance I declared in my class. I can then drag it in with a “get” method, and break on that class’s variables, or set the struct to something else. See below:

If that doesn’t work, might be good to post a screen shot of your class/struct definitions.

Unfortunately not, because what I have is:

UPROPERTY(BlueprintReadWrite,EditAnywhere)
FYourCustomStruct* YourReferenceName

and the UPROPERTY macro afaik doesn’t like pointers, only variables :\

the code above returns an error btw, indicating an inappropriate type for the macro.

I guess I wasn’t clear enough in my description, sorry for that!

using Benergy’s example, I have the following inside my Character Class:

 FYourCustomStruct* YourReferenceName;

I then created a Child BP of this character class for use in BP in the editor, mostly so I can create UI visuals much easier.

At the moment, I don’t know if its possible to expose the above reference to that child BP, so that I can access it in the editor.

What I could do is copy the target data into a variable held by the class, and UPROPERTY that, so I can use it. But since there can possibly be thousands of this actor in the game at any time, all making a separate call to that database, copying that data seems fairly inefficient and I’m wont to actually implement that. (but I will if I get desperate.)

Hi Raxis,

Okay, I did some digging about this and found a few threads which are relevent there.

The first one: How do I expose a USTRUCT by reference/pointer? - Editor Scripting - Epic Developer Community Forums
Indicates that you can’t really store exposed USTRUCT references in your BP.

UE4 treats struct references as copies basically, and even if you have a C++ function which returns a struct my reference, I believe UE4 will still create a copy before giving it to you in your BP. The thread relevant to that issue is: Pass blueprint UStruct by reference - Programming & Scripting - Epic Developer Community Forums

I did some experimenting and found a workaround to this issue. This solution isn’t as elegant as just storing a reference to a struct and modifying the values, which apparently UE4 doesn’t like, but it gets the job done without requiring you to create dummy structs and manually copy each element over…

Workaround:

Basically, in the C++ class that has the struct pointer, you can define a getter and a setter method to obtain the struct for your blueprints. Something like

In my class header file, my class has a reference to a USTRUCT of type “Frar” which I call “myRar”

... class definition in header ...
{
	GENERATED_BODY()

public:

    // Note i don't use UPROPERTY here! It will fail to compile if I do.
    // Just assumy "myRar" is set up somewhere, using a USTRUCT and the members have
    // UPROPERTY defined on them appropriately...
	Frar* myRar;

    ... rest of class member definitions ...

    //
    // The following are my getters and setters (by value! to access the myRar
    // struct I'm holding
    //

	// Initializes "myRar" with a new operator
	UFUNCTION(BlueprintCallable)
    void CreateMyRar();

	// Gets "myRar" value.  Note that even though this returns by reference,
	// UE4 seems to treat it as return by value
	UFUNCTION(BlueprintCallable)
	void GetMyRar(Frar & getVal);

	// Sets the "myRar" value by copying over everything from the input "setVal" struct
	UFUNCTION(BlueprintCallable)
	void SetMyRar(const Frar & setVal);

In the class CPP file, implement the getters and setters (which just copy values and return copy of struct, even though inputs/outputs are references):

void URayBox::CreateMyRar()
{
	myRar = new Frar;
}

void URayBox::GetMyRar(Frar & getVal)
{
	getVal = *myRar;
}

void URayBox::SetMyRar(const Frar & setVal)
{
	*myRar = setVal;
}

With these getters and setters set up, you can access the “myRar” reference from the blueprint.

Basically what the blueprint is doing is this:

BeginPlay: Initialize my “myRar” reference (note you can initialize this however you want…I just chose to make a custom function for this for demonstration). Next, it’s calling “GetMyRar” which returns myRar by value . Next I’m calling “Set members in …” function to set the members in the struct by value. When I did this, after adding the “Set members in” node, I had to right click on it and click “Restore all structure pins” for the struct’s members to show up. Next, I’m calling “Set My Rar” which will copy the updated rar struct to my “myRar” reference in the class.

In the “PlayerCollision” event: I’m calling “Get My Rar” function, then calling "Break " to access the individual members of the copy returned by “Get My Rar”. Then I add the two members together (arbitrary operation), and call “Set members in …” again. Note this time, since I didn’t want all of the member pins exposed (since I don’t want to set the value of “dummyVal”) I had to right click on each pin I didn’t want, and clicked “Remove this struct variable pin”. that way the “dummyVal” isn’t updated and reatins whatever value it has. Then I call “Set My Rar” again to copy to my classes “myRar” reference.

Okay, after I posted my last workaround, I found an even better way to achieve what you want, without requiring more inefficient copies, and even lets you hold values of your struct reference within your class blueprints. Since AnswerHub only allows a small amount of characters for comments, I have to post this as a separate “answer”.

The idea is to wrap your struct reference inside a normal USTRUCT wrapper struct, and hold that by value in the class using the normal UPROPERTY to expose the wrapper to blueprints. Internally, the wrapper struct just holds a pointer to your reference, and the wrapper can be copied by value and the pointer will stay the same. This doesn’t require copying all of the struct members, only the pointer, so it’s efficient to pass around a lot. You can then create static getters/setters that work on that wrapper struct to get the actual data, and have the C++ code for the getters/settes actually do the pointer dereferencing internally. Since the getters/setters would be static, they can be called from any class, anywhere.

In my example header, Frar is the actual struct with data, “FrarWrapper” is just a wrapper that will get passed around by value, but the pointer value will always hold the reference to your actual struct:

struct Frar {

	int myTest;

	int dummyVal;
};
	
USTRUCT(BlueprintType)
struct FrarWrapper {
	GENERATED_USTRUCT_BODY()

	Frar * fRarPointer;	
};

/**
 * 
 */
UCLASS(Blueprintable, ClassGroup=(Gravi), editinlinenew, meta=(BlueprintSpawnableComponent) )
class GRAVIPROTOTYPE_API URayBox : public UActorComponent 
{
	GENERATED_BODY()

public:

    // The reference to your struct.
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FrarWrapper myFrarRef;

    // Static getter for Frar's myTest value
	UFUNCTION(BlueprintPure, Category="Utilities")
	static int GetFrarMyTest(const FrarWrapper & frarRef);

    // Static setter for Frar's myTest value
	UFUNCTION(BlueprintCallable, Category="Utilities")
	static void SetFrarMyTest(FrarWrapper frarRef, int testVal);

In the CPP, do all the pointer dereferencing:

void URayBox::CreateMyRar()
{
	myFrarRef.fRarPointer = new Frar;
}

int URayBox::GetFrarMyTest(const FrarWrapper & frarRef)
{
	return frarRef.fRarPointer->myTest;
}

void URayBox::SetFrarMyTest(FrarWrapper frarRef, int testVal)
{
	frarRef.fRarPointer->myTest = testVal;
}

In the blueprint, UE4 will pass the reference “frarRef” around by value, but since it’s holding a pointer, the underlying reference will be fine! Just use the static getter/setter methods when you need to access the data. You can even create more complex getters/setters as you need:

you are a god! I’ll test it asap, and let you know how it goes, but it seems super sound to me :smiley: thanks for this!

This worked fantastically!

Cool, glad it worked for you!

In the future if I find better solutions I’ll update here. I was thinking of possibly using templates for the struct pointer wrapper to make it more generic, maybe some macros to auto-generate the getters/setter functions, but don’t know how much work that would involve, or if its even feasible… anyways, cheers!