In this lesson, you will learn how to create lightweight, stack-allocated UStruct containers to organize your data efficiently while keeping it compatible with Unreal’s reflection system.
Why UStruct instead of UObject?
In our previous lessons, we spent a lot of time managing UObject lifetimes through garbage collection and smart pointers. However, not every piece of data needs the overhead of being a "managed object." If you have a simple collection of variables—like a character's inventory slot or a quest objective’s state—UStruct is your best tool.
Because UStructs are stack-allocated, they are significantly faster to instantiate and don't require the garbage collector to track them individually. They are perfect for "Plain Old Data" (POD) that you want to easily store in arrays or pass by value.
Defining Your Struct
To create a UStruct, you must follow a specific syntax so the Unreal Header Tool (UHT) can recognize it:
USTRUCT(BlueprintType)
struct FQuestData
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FString QuestName;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
int32 DifficultyLevel;
// UStructs are often used as simple data containers
FQuestData() : QuestName(TEXT("New Quest")), DifficultyLevel(1) {}
};
Key Rules for UStructs
- The F-Prefix: By convention, all
UStructnames must start with anF. GENERATED_BODY(): Just likeUObjectclasses, this macro is mandatory. It enables the reflection system to see your struct's members, allowing them to appear in the Unreal Editor details panel.- Serialization: Because you marked the members with
UPROPERTY(), Unreal will automatically handle the serialization of this data when you save your game or edit it in the inspector. - No Inheritance: Unlike
UObject,UStructcannot inherit from other structs. They are designed to be flat, lightweight compositions.
By using UStructs for your raw data and UObjects for complex, behavior-heavy systems, you maintain a highly performant and organized memory architecture.
Key Takeaway: Use UStructs for lightweight, performance-critical data containers that need to interact with the Unreal Editor but don't require the overhead of garbage-collected object lifetimes.