How do I expose a USTRUCT by reference/pointer?

I have an object that’s a proxy for an IDetailsView. It’s a proxy because it needs to combine two objects from different modules, and let the user edit their properties. Fine.

In trying to make the structure less grody, I’ve been trying to simply add a reference to the USTRUCT on one side of the equation into the proxy as a property. That doesn’t work.

To be clear:

UPROPERTY()
FSubmeshParameters *SubmeshParams;

Is illegal.

error : In DestructibleSubmeshParamsProxy: Inappropriate '*' on variable of type 'FSubmeshParameters', cannot have an exposed pointer to this type.

I’m sure there’s good reasons for that. But there’s lots of good reasons to avoid passing large structs around by value. It also won’t let me put it into a TSharedPtr. Using a C++ reference also is a problem since references don’t make good members.

A solution would be to make it a UObject, but unfortunately that’s not a good solution for me. I might just have to do it though, I really don’t want to be copying data around.

So, here’s the question again in brief:

Is there a way to expose a USTRUCT by reference in another UObject so that its properties may be edited directly?

If not, there really should be.

1 Like

Hi,

No, you cannot do that, nor are there any plans to expose USTRUCT properties in that way. USTRUCTs are value types and are designed to be stored directly. If you want to share pointers to your data as properties, you need a UObject.

Steve

1 Like

Hi, sorry for the bump, but one problem I am running into is that UStructs are easily replicatable, but UObjects do not support replication. What I am trying to do is have a polymorphic set of data holders in my playerState, and since UStructs should only be value types I can’t use those, since it would only ever have the size of the base struct in the class and cause corruption with any child data.

I don’t want to use an actor, because literally all I want is a data blob, and an actor is way too much overkill.

Sorry for DP. This would also be useful for AInfo, because AActor just does WAY too much.

Rather than bump this post, I would create a new thread, so that someone more familiar with implementing polymorphic replication without actors may be able to find it.

Steve

Sorry for bumping this after a whole year, but is this still up to date? Are pointers or references to USTRUCTs still not allowed? I have stored an array of USTRUCTs in a singleton and I would like to reference them in instances of some classes without having to duplicate the whole object… Also about replication: Doesn’t UE4 automatically replicate UPROPERTYs of UObject classes?

Nothing has changed here in the past year.

Pointers and references to USTRUCTs are ‘allowed’ but they aren’t managed and they can’t be UPROPERTYs, so you will have to manage them yourself, i.e. you need to handle when the instances change/destruct and replace/null your pointers as appropriate, just like you would have to do with any other regular C++ object.

Unlike UCLASSes, USTRUCTs aren’t special when it comes to object lifetimes.

Steve

Wow, thanks for the quick reply!!
This means I can safely use them for constant data, which holds true in my case. If I were to use UCLASSes, would this cause considerable overhead? I would probably have hundreds of instances always lying around somewhere.

Depends what you mean by ‘constant’. If you have something like:

UCLASS()
class UThing : public UObject
{
    GENERATED_BODY()

public:
    UPROPERTY()
    const FMyStruct DoesntChange;
};

UCLASS()
class UThing2 : public UObject
{
    GENERATED_BODY()

public:
    const FMyStruct* Ptr; // Points to a UThing::DoesntChange
};

… then that pointer will still only be valid as long as the UThing it’s pointing to remains un-garbage-collected.

UCLASSes do bring some amount of overhead: they will be added to the global list of objects which will impact object iteration, they will have additional state for dynamic typing/names/class/field iteration etc, they will have a vtable, they will have additional reflection code which you may or may not use… and the more instances you have of them, the more pressure there will be on the garbage collector (i.e. slower).

Steve

Then I will have to find a way to avoid UCLASSes :smiley:
What I mean with constant is this: I have a singleton, which holds - for example - an array of USTRUCTs. The data can be set in the editor via Blueprints. I have a class, which will hold a reference to one of the elements of that array (maybe I will just save the index). The element will tell the UCLASS (which is an AActor) what to render, it is something like a configuration…

Since the singleton instance is alive and valid for as long as the engine/game is running, this should be safe, shouldnt it?

Yeah, it should be fine.

Steve

Sorry, one more question about setting USTRUCTs up, this may be a little unrelated though xD:

I created a new header file for my USTRUCT in order to include it without an overhead wherever I need it. Is this a terrible Idea? Should I rather create a new class, inheriting from nothing, through the Content Browser/Egnine Menu?

You can’t have a UCLASS which inherits nothing - you always inherit at least UObject, which brings along most of that baggage I speak of.

I don’t think there’s anything wrong with having a struct, as long as you’re suitably careful about how you point to those instances. UObjects save you from a lot of that, but sometimes you just need to make an engineering decision of simplicity vs efficiency.

Steve

I think I expressed myself inaccurately. I did not mean that I created a new UCLASS class. I was asking which way would be most appropriate to create new header/source files for a new USTRUCT. Should I add a C++ asset without inheritance from the content browser menu or create the header files directly in visual studio? I first tried to create a USTRUCT directly from the content browser as an asset, but I could not figure out how to reference the struct in my C++ code… Which is why I thought that we need to define USTRUCTs in c++ files if we want to access them in C++. Currently, I have defined it inside the header/source files of my Singleton Class, but I would like to move the definition into a seperate header/source file.
Im sorry about my misleading comment above.

i have a static function library that holds all of my common USTRUCTs. its pretty simple, and as far as i can tell, it doesn’t seem to be inefficient. is this a decent way to do it?

Creating a struct in the context browser just creates a .h file and a .cpp file with a given template, right? So it doesn’t matter how you create them. Just make sure you compile the new code once you’ve added it - adding via the content browser does that for you automatically.

Creating USTRUCTs in its own header or inside the header for another class are both fine. We don’t really distinguish between the two cases and it’s up to you where to define it where it makes most sense for you in your game. It does need to be inside a folder named Public, Private or Classes though. The Classes folder is actually deprecated, so don’t go for that.

If you can though, try to define them in the right place to start with, otherwise you’ll need to deal with redirectors once saved assets start to refer to them.

Steve

Hi, sorry for bump this up again, but I was able to add a USTRUCT inside a data table(just for the sake of organization) and that STRUCT contains a TArray of UAnimMontages(which is basically the set of animations to play with that weapon specifically). Although playing those animations on the server is fine, on the client I can never find those animations… Is Pointers inside Ustructs replicated if we add a UPROPERTY on it?

If I ask to print the variable name it shows the proper names of the animations, but we can never play it from the client sides.

Hi,

I’m afraid I can’t help with data table replication issues. I suggest posting a new topic for your issue so that it gets triaged appropriately.

Steve