언리얼 엔진

[언리얼 엔진] UCLASS와 USTRUCT의 차이 정리

dhlee-dev 2026. 6. 8. 22:06

이전 글에서는 UObject, 언리얼 객체 시스템의 기반이라는 내용을 정리했다.

이번에는 그와 이어서 UCLASSUSTRUCT의 차이를 정리해보려고 한다.

일반 C++에서는 classstruct의 차이가 기본 접근 지정자 정도이다.
class는 기본이 private, struct는 기본이 public이라는 차이가 있을 뿐
문법적으로는 거의 같은 방식으로 사용할 수 있다.

하지만 언리얼 엔진에서 사용하는 UCLASSUSTRUCT는 단순히 접근 지정자만 다른 개념이 아니다.

실제로 코드를 작성하다 보면 객체로서 관리해야 하는 타입은 UCLASS로 만들고,
데이터를 값처럼 다루는 타입은 USTRUCT로 만드는 경우가 많다.

처음에는 둘 다 리플렉션을 위한 매크로 정도로 생각했지만,
공부하면서 사용 목적과 동작 방식이 다르다는 것을 알게 되었다.

그래서 이번 글에서는 UCLASSUSTRUCT가 각각 어떤 경우에 사용되는지,
그리고 둘 사이에 어떤 차이가 있는지 정리해보려고 한다.


UCLASS란?

UCLASSUObject 계열 클래스에 사용하는 매크로이다.

UCLASS가 붙은 클래스는 언리얼 리플렉션 시스템에 등록될 수 있고,
이를 통해 언리얼 엔진의 여러 기능과 연결될 수 있다.

대표적으로 다음과 같은 특징이 있다.

  • UObject 계열 클래스에 사용한다.
  • 가비지 컬렉션 대상이 될 수 있다.
  • UFUNCTION을 사용할 수 있다.
  • Blueprintable 지정 시 블루프린트 상속이 가능하다.
  • 보통 포인터로 참조해서 사용한다.
  • CDO를 가진다.

UCLASS 기반 클래스는 UObject 계열이기 때문에
언리얼의 GC, 리플렉션, 직렬화, 블루프린트 연동 같은 기능과 연결된다.


USTRUCT란?

USTRUCT는 언리얼 리플렉션 시스템에 구조체를 등록할 때 사용하는 매크로이다.
USTRUCT는 보통 데이터를 묶어서 표현할 때 사용한다.

USTRUCT(BlueprintType)
struct FItemData
{
    GENERATED_BODY()

    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    int32 ItemID = 0;

    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    FString ItemName;
};

USTRUCT의 특징은 다음과 같다.

  • 데이터 구조를 표현할 때 사용한다.
  • 값 타입에 가까우며, 값으로 전달하면 복사된다.
  • 필요하면 참조나 포인터로 전달할 수 있다.
  • UObject 계열이 아니므로 일반적으로 GC 대상이 아니다.
  • UFUNCTION을 가질 수 없다.
  • 블루프린트 상속은 불가능하다.
  • CDO를 가지지 않는다.

즉, USTRUCT는 엔진 객체라기보다는
언리얼 리플렉션 시스템에 등록할 수 있는 데이터 구조에 가깝다.


UCLASS와 USTRUCT 비교

정리하면 UCLASSUSTRUCT는 다음과 같이 비교할 수 있다.

구분 UCLASS USTRUCT
대상 UObject 계열 클래스 데이터 구조체
성격 객체 타입 값 타입
GC 대상 가능 일반적으로 아님
UFUNCTION 사용 가능 사용 불가
블루프린트 상속 Blueprintable 지정 시 가능 불가능
블루프린트 변수 타입 가능 BlueprintType 지정 시 가능
CDO 있음 없음
사용 방식 보통 포인터로 참조 값으로 다루기 쉽고, 필요하면 참조로 전달 가능

UCLASS는 언리얼 엔진이 관리하는 객체를 만들 때 사용하고,
USTRUCT는 데이터를 묶어서 표현할 때 사용하는 경우가 많다.


USTRUCT에서는 UFUNCTION을 사용할 수 없다

UFUNCTION은 언리얼 리플렉션 시스템에 함수를 등록하기 위한 매크로이다.
주로 다음과 같은 기능에 사용된다.

  • 블루프린트 호출
  • RPC
  • Dynamic Delegate 바인딩

UFUNCTIONUCLASS 또는 언리얼 인터페이스의 IInterface scope에서 사용할 수 있다.
반면 USTRUCT는 언리얼 리플렉션 시스템에서 함수 등록 대상으로 다뤄지지 않기 때문에 UFUNCTION을 가질 수 없다.

즉, 함수 기능을 엔진 시스템과 연결해야 한다면 USTRUCT보다는
UCLASS 기반 클래스를 사용하는 것이 맞다.


CDO 유무 차이

UCLASS 기반 클래스는 CDO를 가진다.
CDO는 클래스마다 하나씩 존재하는 기본 객체이다.

새로운 UObject 인스턴스를 만들 때는 이 CDO를 기본 템플릿처럼 사용해 초기화할 수 있다.
반면 USTRUCTUObject 인스턴스가 아니기 때문에 CDO를 가지지 않는다.

USTRUCT의 기본값은 생성자나 멤버 기본값을 통해 처리한다.

USTRUCT(BlueprintType)
struct FStatData
{
    GENERATED_BODY()

    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    int32 HP = 100;

    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    int32 Attack = 10;
};

즉, UCLASS는 엔진 객체로서 기본 객체인 CDO를 가지고,
USTRUCT는 일반적인 값 타입 구조체처럼 기본값을 직접 정의하는 방식에 가깝다.


Blueprintable과 BlueprintType 차이

UCLASSUSTRUCT를 공부하다 보면 BlueprintableBlueprintType도 함께 헷갈릴 수 있다.

Blueprintable

Blueprintable은 이 클래스를 기반으로 블루프린트 클래스를 만들 수 있다는 의미이다.

UCLASS(Blueprintable)
class MYPROJECT_API UMyObject : public UObject
{
    GENERATED_BODY()
};

예를 들어 AActor는 기본적으로 블루프린트로 상속해서 사용할 수 있기 때문에
AActor를 상속받은 클래스는 블루프린트 클래스로 만들 수 있다.

반면 UObject를 직접 상속받는 클래스라면 필요에 따라 Blueprintable을 직접 지정해야 할 수 있다.

BlueprintType

BlueprintType은 해당 타입을 블루프린트 변수 타입으로 사용할 수 있다는 의미이다.

USTRUCT(BlueprintType)
struct FItemData
{
    GENERATED_BODY()
};

즉, Blueprintable은 블루프린트 클래스로 상속 가능한지에 대한 것이고,
BlueprintType은 블루프린트에서 변수 타입으로 사용할 수 있는지에 대한 것이다.


언제 UCLASS를 쓰고 언제 USTRUCT를 쓸까?

간단하게 생각하면 다음과 같이 구분할 수 있다.

UCLASS는 객체로서 생명주기 관리가 필요하거나 엔진 기능과 깊게 연결되어야 할 때 사용한다.
예를 들어 다음과 같은 경우에는 UCLASS가 적합하다.

  • UObject 기반 객체가 필요할 때
  • GC 대상 객체로 관리하고 싶을 때
  • UFUNCTION이 필요할 때
  • 블루프린트 상속이 필요할 때
  • Actor나 Component처럼 엔진 객체로 다루고 싶을 때

반면 USTRUCT는 단순한 데이터 묶음을 표현할 때 적합하다.
예를 들어 다음과 같은 경우에는 USTRUCT가 적합하다.

  • 아이템 데이터
  • 스탯 데이터
  • 설정 데이터
  • 데이터 테이블 행 구조체
  • 복사 가능한 값 타입 데이터

특히 데이터 테이블을 만들 때는 FTableRowBase를 상속받은 USTRUCT를 사용하는 경우가 많다.

USTRUCT(BlueprintType)
struct FItemTableRow : public FTableRowBase
{
    GENERATED_BODY()

    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    int32 ItemID = 0;

    UPROPERTY(EditAnywhere, BlueprintReadWrite)
    FString ItemName;
};

정리

UCLASSUSTRUCT는 둘 다 언리얼 리플렉션 시스템과 관련이 있다.

UCLASSUObject 계열 클래스를 엔진 객체로 다루기 위해 사용한다.

  • UObject 계열 클래스에 사용한다.
  • GC 대상이 될 수 있다.
  • UFUNCTION을 사용할 수 있다.
  • Blueprintable 지정 시 블루프린트 상속이 가능하다.
  • CDO를 가진다.
  • 보통 포인터로 참조해서 사용한다.

USTRUCT는 데이터를 묶어서 표현하기 위한 값 타입 구조체에 가깝다.

  • 데이터 구조를 표현할 때 사용한다.
  • 일반적으로 GC 대상이 아니다.
  • UFUNCTION을 사용할 수 없다.
  • 블루프린트 상속은 불가능하다.
  • BlueprintType을 통해 블루프린트 변수 타입으로 사용할 수 있다.
  • CDO를 가지지 않는다.
  • 값 타입에 가깝고, 필요하면 참조로 전달할 수 있다.

따라서 객체로서 엔진 시스템과 연결해야 한다면 UCLASS,
단순히 데이터를 묶어서 표현하고 싶다면 USTRUCT를 사용하는 것이 적합하다.


마무리

이전에 C++에서 structclass의 차이를 공부했을 때는
둘의 차이가 기본 접근 지정자 정도라고 정리했었다.

하지만 언리얼 엔진에서의 UCLASSUSTRUCT
단순히 C++의 class, struct 차이처럼 볼 수 있는 개념이 아니었다.

둘 다 언리얼 리플렉션 시스템과 관련이 있지만,
UCLASSUObject 계열 클래스를 엔진 객체로 등록하기 위한 것이고,
USTRUCT는 구조체를 리플렉션 시스템에 등록하기 위한 것이다.

특히 GC 대상 여부, UFUNCTION 사용 가능 여부, CDO 유무, 블루프린트 상속 가능 여부처럼
기능적으로 명확한 차이가 있다는 점을 알게 되었다.

앞으로도 언리얼 C++을 공부하면서
문법뿐만 아니라 엔진 내부에서 어떤 의미를 가지는지도 함께 정리해봐야겠다.