C++ / USTRUCT 사용자 정의 구조체 만들기

 

작성버전 :: 4.20.3

 

구조체는 기존에 존재는 데이터 타입을 조합하여 새로운 데이터 타입을 만들어내는 유용한 개념이다.

 

struct UserDefinedStruct

{

public:

    int i;

    float f;

};

 

일반적인 C++ 프로젝트에서는 구조체를 위와 같이 정의하고 사용하게 된다.

 

하지만 언리얼 엔진 프로젝트에서 이러한 정규 구조체는 C++ 코드 내부에서는 사용될 수 있지만, 에디터의 디테일 패널에 노출되지 않고, 블루프린트에서도 사용이 불가능하다.

 

에디터에서 사용가능한 구조체를 만들고자 한다면 언리얼 구조체 즉, USTRUCT를 만들어야 한다.

 

 

블루프린트에서만 사용할 구조체라면 위의 이미지와 같은 방법으로 구조체를 생성할 수 있는데, 블루프린트 구조체는 C++ 코드에서는 사용할 수 없다. 하지만 C++ 코드에서 만든 구조체는 C++ 코드는 물론 블루프린트에서도 사용할 수 있다는 장점이 있다.

 

C++ 언리얼 구조체는 간단한 블루프린트 구조체 생성 방법과 비교했을 때, 엔진 내부에서 명시적인 생성 방법이 없기 때문에 생성 과정이 조금 복잡하다.

 

 

언리얼 구조체 만들기

 

언리얼 구조체를 만드는 과정을 따라가보도록 하자.

 

 

 

 

 

우선 사용자가 정의한 UStruct를 담을 헤더를 만들어야 한다. 만약 구조체가 특정한 클래스에서만 자주 사용될 것이라면 그 클래스의 헤더 파일 하단에 구조체를 정의하는 편이 좋지만, 범용적으로 여러 곳에서 사용될 구조체라면 사용자가 정의한 헤더에 몰아서 정의하는 편이 좋다.

 

CustomStruct00 클래스의 추가가 끝났다면 아래의 예시 코드와 같이 클래스 정의 아래 쪽에 커스텀 구조체를 정의해보자.

 

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "CustomStruct00.generated.h"

UCLASS()
class CUSTOMSTRUCTTEST_API ACustomStruct00 : public AActor
{
    GENERATED_BODY()
   
public:   
    // Sets default values for this actor's properties
    ACustomStruct00();

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public:   
    // Called every frame
    virtual void Tick(float DeltaTime) override;
};


USTRUCT(Atomic, BlueprintType)
struct FCustomStruct
{
    GENERATED_BODY()
public:
    UPROPERTY(EditAnywhere, BlueprintReadWrite)
        AActor* actor;
    UPROPERTY(EditAnywhere, BlueprintReadWrite)
        float f;
    UPROPERTY(EditAnywhere, BlueprintReadWrite)
        int32 i;
};

 

클래스에는 UCLASS() 매크로가 붙지만 구조체의 경우에는 USTRUCT() 매크로가 붙는다. 그리고 구조체 지정자는 Atomic과 BlueprintType으로 지정해뒀는데 Atomic은 이 구조체가 항상 하나의 단위로 직렬화(Serialize)됨을 의미하고 BlueprintType은 이 구조체가 블루프린트에서 사용될 수 있음을 의미한다.

 

만약 이 구조체가 에디터의 디테일 창에서 표시되고 수정 가능하기만 원한다면 지정자를 Atomic으로만 설정하기를 권한다. 또한 모든 멤버 변수의 UPROPERTY() 매크로의 지정자를 EditAnywhere로 설정해야 한다.

 

혹은 구조체가 디테일 창에서는 보이지 않고 코드 내부나 블루프린트에서만 사용되기를 원한다면 USTRUCT() 매크로의 지정자를 BlueprintType으로, UPROPERTY() 매크로의 지정자를 BlueprintReadWrite로 설정해야 한다.

그리고 구조체의 이름은 F로 시작되게 작성해야 하며, 댕글링(Dangling) 포인터 문제에 대해서 보호받기 위해서 구조체의 모든 멤버 변수들에 UPROPERTY() 매크로를 붙이는 것을 권장한다.

 

또한 구조체의 멤버 변수에 포인터를 사용한다면 깊은 복사 얕은 복사 문제에 주의를 기울여야 한다.

 

사용할 구조체를 모두 정의했다면, 이 구조체를 사용할 코드의 헤더에 CustomStruct00.h를 포함시켜준다.

 

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "CustomStruct00.h"
#include "TestActor.generated.h"

UCLASS()
class CUSTOMSTRUCTTEST_API ATestActor : public AActor
{
    GENERATED_BODY()
   
public:   
    // Sets default values for this actor's properties
    ATestActor();

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public:   
    // Called every frame
    virtual void Tick(float DeltaTime) override;

    UPROPERTY(EditAnywhere)
    FCustomStruct st;
};

 

 

 

이렇게 구조체를 테스트 액터의 멤버 변수로 추가시킨 후 에디터로 돌아가서 컴파일을 해주고, 액터를 레벨에 배치하고 선택해보면 위의 이미지처럼 구조체가 디테일 패널에서 수정가능하록 노출된 것을 확인할 수 있다.

 

Tip :: 이후에 구조체의 멤버 변수 종류를 수정하고 컴파일했을 때, 디테일 패널에 곧바로 적용이 되지 않는 문제가 가끔있는데 이런 경우 해당 구조체를 가진 클래스의 멤버 변수에 임시 변수 하나를 추가하고 컴파일하면 적용이 된다.

 

 

 

 

생성한 구조체 블루프린트에서 사용하기(Use Custom Struct at Blueprint)

 

C++ 코드에서 정의한 구조체를 블루프린트에서 사용하는 방법은 간단하다.

 

 

 

블루프린트에서 정의한 CustomStruct 변수 유형으로 변수를 추가할 수 있다.

 

 

 

이미지와 같이 이벤트 그래프에서 우클릭을 한 뒤 정의한 구조체의 이름을 검색하면 이벤트 플로우 도중에 CustomStruct를 만들거나 구조체를 분해해서 구조체의 변수를 따로 뽑아내서 사용할 수도 있다.

 


 

참고

 

Unreal Engine 4 Wiki :: Structs, USTRUCTS(), They're Awesome(https://wiki.unrealengine.com/Structs,_USTRUCTS(),_They%27re_Awesome)

Unreal Engine 4 Wiki :: How To Make UStruct(https://wiki.unrealengine.com/How_To_Make_UStruct)

반응형
  1. 교육생 2020.12.03 16:53

    안녕하세요 언리얼4 입문하게된 교육생입니다
    영상하고 항상 잘 보고있습니다
    C++로 언리얼을 접근하려는데
    어려움이 많아서 도움을 요청하고 싶어서 댓글달아 봅니다
    몬스터를 UEnum으로 이름의 목록을 구성하여
    구조체로 그에맞는 몬스터를 뽑아오려고 생각하여
    USTRUCT 에서 폰을 추가하였고
    editanywhrer로 둘다 사용할수있게 하였는데
    에디터창에서 사용할 폰을 삽입했을시
    블루프린트에서 지정된 폰이 어떤건지 인식이 안되던데 도움좀 받고싶습니다
    너무 설명이 어려운거같은데
    게임개발자로 거듭나기위해 도움을 많이 받고싶어요

+ Recent posts