Using UObjects as you would a struct

Hello all. I have found myself using UObject-inheriting classes as I would a struct in normal C++. The reason for that is that I will often need an object that keeps a reference to another object or has an array of another object. I may also need to have an array of that object in another class. Examples include the nodes of a node graph.

Using USTRUCT for that purpose has given me a lot of difficulties, so instead, I create a UCLASS which inherits from UObject, and it can contain the references as required, and also be put in a TArray in another class. It’s also properly managed by the garbage collector.

I’d like to know if that is a terrible way of doing things, and if so, what would be the proper flow for those kinds of designs. It seems to work fine, but I feel like it may be adding a lot of unnecessary overhead.

When even “pins” of nodes or “primitive” variables in Blueprints are boxed UObjects… Then why not?!
The boat is already loaded anyway.

Huh? Pins of nodes aren’t UObjects. Although the name UEdGraphPin, starting with U while not being a UClass, is pretty misleading…

Blueprint variables have a single UObject representation in the reflection data, for instances of the BP they will be added directly after the end of the native class, as if they were native members. It’s actually quite clever.

For what it’s worth, @Xylord, in many cases I use the exact same approach, and I think it works great. As for how much additional overhead it incurs, I can’t exactly say, but you should be able to profile your performance and memory usage to possibly find out yourself.

I figure, unless you’re going to instantiate a huge number of UCLASS objects, or unless you’re developing for devices with very limited horsepower, I doubt using this UCLASS approach is going to be a performance killer compared to using regular structs. As for me, my uses so far have not involved large numbers of objects, and I’m developing for PCs, so performance effects of this setup haven’t even crossed my mind.

UObject’s have a memory footprint of 56 Bytes. This will most likely be smaller than whatever data you’re storing ( 1 Vector is 12 bytes ). I don’t know how much external memory is spent keeping track of them, but I imagine there will be a few pointers to them lying around.

Overhead that would likely come into play would be CPU cache misses for that memory if you’re searching the Arrays very frequently (like, multiple times every tick for large arrays). I have some custom asset types which have Arrays and / or Maps of UObjects, but we only traverse them very infrequently so it’s not a problem.