【Unreal Engine】Managing Complex Data with Structs

Created: 2025-12-12

Structs for grouping related data together. Creation methods in Blueprint and C++, Make/Break Struct node usage, and Data Table integration.

Challenges of Complex Data Management and the Need for Structs

When developing games with Unreal Engine, you'll inevitably encounter situations where you want to handle multiple related pieces of data as a group—character stats, item properties, complex configuration values, etc.

For example, consider managing character "health," "stamina," and "attack power." Keeping these as separate variables causes problems like:

  1. Reduced Readability: Multiple variables scattered around, making it unclear which variables belong to which data set.
  2. Blueprint Node Clutter: Too many function arguments, or having to "Set" and "Get" related variables individually creates many nodes, making graphs complex.
  3. Data Table Inefficiency: When using DataTable, related data becomes columns instead of rows, making data structuring difficult.

The powerful tool for solving these challenges and managing data logically and efficiently is Unreal Engine's Struct.


What is a Struct?

A struct is a mechanism that bundles variables of different data types (Variable Type) together to define a new custom data type.

Think of a struct like a "business card." A business card contains different types of information like "name (string)," "title (string)," "phone number (integer)," organized under the common theme of a single person.

In Unreal Engine, structs can be defined and used in both Blueprint and C++.

CharacteristicStructArray
Storable Data TypesCan mix different data typesSingle data type only
PurposeGroup logically related dataHold same-type data as a list
NatureTreated as Value TypeTreated as Value Type

Relationship Between TArray and UObject

TArray itself is copied as a value type, but when storing UObject pointers like TArray<UObject*>, the contents are treated as reference types. Even if you copy the array, the stored UObjects point to the same instances.

USTRUCT and FStruct

When defining structs in C++, use the USTRUCT() macro to have them recognized by Unreal Engine's type system.

  • USTRUCT(): Used to define structs compatible with Unreal Engine's garbage collection and reflection system.
  • F Prefix: By Unreal Engine convention, struct names have the F prefix (e.g., FCharacterStats).

Practice! Creating and Using Structs in Blueprint

For beginners, the easiest approach is defining structs in Blueprint.

1. Create the Struct

  1. Right-click in Content Browser and select "Blueprint" -> "Structure."
  2. Give it a name (e.g., F_ItemData).
  3. Double-click the created struct to open it and add needed variables with "New Variable."

Example: Item Data Struct F_ItemData

Variable NameTypeRole
ItemNameStringItem name
ItemIDIntegerItem ID
IconTextureTexture 2D Object ReferenceIcon image
StackableBooleanWhether stackable

2. Using Structs (Make/Break Struct Nodes)

Structs can easily input and output data using "Make Struct" and "Break Struct" nodes in Blueprint graphs.

  • Make F_ItemData (Make Struct): Takes multiple input pins (ItemName, ItemID, etc.) and outputs as a single struct pin. Used when creating new data.
  • Break F_ItemData (Break Struct): Takes a single struct pin as input and expands individual member variables as output pins. Used when extracting data from struct.

This consolidates function and event dispatcher arguments into a single struct, greatly simplifying node wiring.

graph LR
    A[Item Name String] --> M
    B[Item ID Int] --> M
    C[Icon Texture Ref] --> M
    M(Make F_ItemData) --> S[F_ItemData Variable]
    S --> B2(Break F_ItemData)
    B2 --> D[Item Name]
    B2 --> E[Item ID]

Struct Definition in C++ and Exposing to Blueprint

For more advanced data management or when performance is required, define structs in C++ and make them usable from Blueprint.

// CharacterStats.h
#pragma once

#include "CoreMinimal.h"
#include "Engine/DataTable.h" // Needed when using with Data Table
#include "CharacterStats.generated.h"

// USTRUCT() macro to make usable from Blueprint
USTRUCT(BlueprintType)
struct FCharacterStats : public FTableRowBase // Use as Data Table row
{
    GENERATED_BODY()

public:
    // UPROPERTY() macro to make editable in Blueprint
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
    float Health;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
    float Stamina;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats")
    int32 AttackPower;

    // Constructor (set initial values)
    FCharacterStats()
        : Health(100.0f)
        , Stamina(100.0f)
        , AttackPower(10)
    {}
};

Key Points:

  1. USTRUCT(BlueprintType): Makes this struct usable as a data type in Blueprint.
  2. UPROPERTY(EditAnywhere, BlueprintReadWrite): Exposes struct member variables for read/write from Blueprint.
  3. FTableRowBase: Inherit this when you want to use this struct as Data Table rows.

C++-defined structs are automatically recognized on the Blueprint side, and "Make/Break" nodes become available just like Blueprint-created structs.


Common Mistakes and Best Practices

Structs are very convenient, but using them without understanding their nature can cause unexpected problems.

Common Mistake: Treating Structs Like Objects

Structs are Value Types. This means when assigning a struct to another variable or passing it to a function, the entire data is copied.

Example of Mistake: Assigning "Character A's stats" struct to "Character B's stats," then changing "Character B's stats" health—"Character A's stats" isn't affected. This is because data was copied during assignment.

Best Practice: Distinguishing Objects and Structs

Use CaseRecommended TypeReason
Static Data DefinitionStructTreat as simple data collections like item base data, settings values. Excellent compatibility with Data Table.
Dynamic State ManagementUObject / ActorComponentCharacter inventory, in-game ongoing events, etc. Use when unique ID, lifecycle, or dynamic behavior (functions) is needed. These are treated as Reference Types.

Common Mistake: Adding Functions to Structs (Blueprint)

Blueprint structs are pure data containers and cannot have functions (logic).

C++ Structs Can Define Functions

C++ USTRUCT can define regular C++ member functions (though UFUNCTION macro cannot be used). For example, helper functions to calculate health can be inside the struct. However, these functions can't be called directly from Blueprint, so when Blueprint usage is expected, the recommended design is to have logic in a separate class.

Best Practice: Put Logic in Separate Classes

Have structs hold only data, and put logic operating on that data (e.g., damage calculation, status display formatting) in Actors, ActorComponents, or Blueprint Function Libraries. This separates data and logic, improving maintainability.


Key Points for Struct Usage

Structs in Unreal Engine are an essential data management technique for stepping up from beginner to intermediate.

Struct Usage BenefitsDetails
Data EncapsulationLogically group related data, improving code and Blueprint readability.
Data Table IntegrationFoundation for efficiently importing and managing complex game data from Excel or CSV.
Interface SimplificationSignificantly reduce function and event input/output pins, simplifying Blueprint graph wiring.
C++ and Blueprint IntegrationMake robust C++-defined data structures easily usable in Blueprint.

Using structs dramatically organizes your project's data management, evolving toward robust design that withstands large-scale development. Start by choosing your most complex data set and try converting it to a struct.