【Unreal Engine】Implementing Data-Driven Design with Data Assets

Created: 2025-12-12

Data Asset separates logic from data, enabling multiple classes to reference the same data. How to define UDataAsset and criteria for choosing between Data Asset and Data Table.

The Need for Data-Driven Design

When developing games with Unreal Engine (UE), you may face challenges like:

  • Difficulty for designers and planners to adjust data: Enemy stats, item performance, level design parameters—is your game's "data" embedded in C++ code or Blueprints? Every data change requires programmer work, slowing iteration speed.
  • Low data reusability: Are you creating new Blueprint classes for similar items or enemies just because parameters differ slightly? This leads to asset bloat and management complexity.
  • Poor memory efficiency: When multiple actors hold the same data (e.g., weapon base stats), that data gets duplicated in memory.

The solution that resolves these challenges and realizes division of labor between programmers and non-programmers, enabling efficient and flexible development is "Data-Driven Design." Data-driven design clearly separates game logic (behavior) from data (parameters).

And in Unreal Engine, the core enabler of this data-driven design is the "Data Asset."


What is Data Asset

Data Asset is an asset designed to hold only data based on a specific data structure (UDataAsset class).

While Blueprint and C++ classes are templates that hold both "behavior (logic)" and "data (properties)," Data Asset purely defines "data" and allows managing it as an independent asset in the Content Browser.

CharacteristicData AssetBlueprint Class (Actor, etc.)
PurposeHold and share data (parameters)Define behavior (logic) and data
InstantiationNot needed (data itself is the asset)Needed (place in world or spawn)
Memory EfficiencyGood (easy to design sharing data by reference without duplication)Depends on situation (may hold data per instance)
Use CasesEnemy stats, item definitions, configuration valuesPlayer character, doors, UI widgets

Data Asset's greatest advantage is that multiple classes and systems can reference the same data and designers can edit data without touching code.


Creating and Using Data Asset

The procedure for introducing Data Asset is very simple.

Step 1: Define the Data Asset Base Class (C++)

First, create a C++ class defining the data structure you want to hold. This class must inherit from UDataAsset.

GameItemDataAsset.h

#pragma once

#include "CoreMinimal.h"
#include "Engine/DataAsset.h"
#include "GameItemDataAsset.generated.h"

UCLASS(BlueprintType)
class MYPROJECT_API UGameItemDataAsset : public UDataAsset
{
    GENERATED_BODY()

public:
    // Item basic information
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item")
    FText ItemName;

    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item")
    FText ItemDescription;

    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Item")
    UTexture2D* ItemIcon;

    // Item stats
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stats")
    int32 AttackPower;

    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stats")
    int32 DefenseValue;

    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Stats")
    float Weight;
};
  • UCLASS(BlueprintType): Makes this class referenceable from Blueprint.
  • UPROPERTY(EditAnywhere, BlueprintReadOnly): Makes it editable in the Data Asset instance in the Content Browser and read-only accessible from Blueprint.

Step 2: Create Data Asset Instance

  1. Right-click in the Unreal Editor Content Browser.
  2. Select Miscellaneous > Data Asset.
  3. Select the GameItemDataAsset you created from the displayed list.
  4. Name the created asset (e.g., DA_Sword_Basic, DA_Potion_Heal).
  5. Double-click the asset to open it, and designers can freely set each property (ItemName, AttackPower, etc.) in the Details panel.

Step 3: Reference Data Asset from Blueprint

To use Data Asset data in-game, have Blueprint classes (e.g., player, enemy, inventory system) hold a reference to the Data Asset.

  1. Create a variable of type UGameItemDataAsset in the Blueprint class.
  2. Assign the Data Asset instance created in the Content Browser (e.g., DA_Sword_Basic) to this variable.
  3. In the Blueprint graph, get Data Asset properties (e.g., AttackPower) from this variable and use them in game logic.

Blueprint Example (Item Usage Logic)

Node image for getting data from Data Asset reference and using it in logic.

graph TD
    A[Event Use Item] --> B{Get Item Data Asset Reference};
    B --> C[Get Attack Power];
    C --> D[Apply Damage to Target];
    D --> E[Print String: ItemName];

Choosing Between Data Asset and Data Table

Unreal Engine has another data management feature called Data Table besides Data Asset. These have different use cases.

FeatureData AssetData Table
StructureCustom UDataAsset classCustom FTableRowBase struct
Management Unit1 asset = 1 data set1 asset = multiple rows of data (CSV/Excel format)
FlexibilityHigh (complex data structures, asset references possible)Low (limited to simple table format)
EditorsMainly designers/plannersMainly designers/planners (external file editing too)
Suited ForComplex item definitions, config files, unique dataLarge amounts of homogeneous data (e.g., enemy level-based stats, translation text)

Best Practices:

  • Use Data Asset for unique, complex data (e.g., player skill tree settings, specific boss enemy definitions).
  • Use Data Table for large amounts of homogeneous data (e.g., 100 types of potion base stats) and manage with external files (CSV/Excel) for easy batch editing.

Data Asset Applications

Data Asset's true value shines when making the entire game system data-driven.

Application: Status Effect System

Defining status effects (poison, paralysis, etc.) as Data Assets makes adding new effects or adjusting parameters easy.

C++ Data Asset Definition

// StatusEffectDataAsset.h
UCLASS(BlueprintType)
class UStatusEffectDataAsset : public UDataAsset
{
    GENERATED_BODY()

public:
    UPROPERTY(EditAnywhere, BlueprintReadOnly)
    FText EffectName;

    UPROPERTY(EditAnywhere, BlueprintReadOnly)
    float Duration; // Effect duration

    UPROPERTY(EditAnywhere, BlueprintReadOnly)
    float TickDamage; // Damage per second

    // References to other assets like status effect icons, particle systems
    UPROPERTY(EditAnywhere, BlueprintReadOnly)
    UParticleSystem* ParticleEffect;
};

Logic Side (Blueprint/C++)

Design functions that apply status effects to receive Data Asset references instead of concrete damage values or effect durations.

// Function to apply status effect
void UCombatComponent::ApplyStatusEffect(UStatusEffectDataAsset* EffectData, AActor* Target)
{
    // Get Duration and TickDamage from Data Asset and execute logic
    float ActualDuration = EffectData->Duration;
    float DamagePerTick = EffectData->TickDamage;

    // ... actual status effect logic ...
}

This way, programmers only implement ApplyStatusEffect logic once, and designers can add new status effects to the game just by creating new Data Assets (e.g., DA_Poison_Strong, DA_Paralysis_Weak).


Common Mistakes and Best Practices

Common Mistakes

  1. Writing logic in Data Asset: Data Asset is purely for holding "data." Write logic (behavior) in classes that reference it like Actors, Components, or Subsystems.
  2. Overusing Data Asset instead of Data Table: When you want to manage large amounts of homogeneous data row by row, Data Table is more appropriate. Data Assets become cumbersome to manage when there are too many.
  3. Trying to instantiate Data Asset directly: Data Assets exist as assets in the Content Browser and are used by reference. They're not meant to be generated at runtime with NewObject.

Best Practices

  • Unify naming conventions: Add prefixes like DA_ to Data Assets (e.g., DA_Enemy_Goblin) to identify them at a glance.
  • Use Primary Data Asset: Deriving Data Assets from UPrimaryDataAsset enables async loading via Asset Manager and patch target management via Asset Bundles. Essential technique for large projects.
  • Use Data Asset as singleton: Create Data Assets holding game-wide settings (e.g., graphics setting presets, gameplay constants) and reference them from Subsystems to centrally manage global settings.

Key Points for Data Asset Usage

Data Asset in Unreal Engine is a powerful tool for achieving data-driven design.

Key PointDescription
RoleAsset that separates data (parameters) from logic (behavior) and holds only data.
BenefitsEasier data adjustment by designers, improved data reusability, better memory efficiency.
SelectionData Asset for complex, unique data; Data Table for large amounts of homogeneous data.
Design PhilosophyLogic side depends on Data Asset type, concrete values depend on Data Asset instances.

Properly utilizing Data Asset makes Unreal Engine development more flexible and efficient. Try incorporating data-driven design into your project.