사용자 정의 데이터 형식인 구조체도 마킹을 해서 활용할 수 있다. USRUCT를 이용할 경우는 다음과 같은 3가지 용도가 존재한다. 그 중에서 리플렉션 기능은 네트워크 공부할 때 다루고 이번 포스트에서는 다루지 않는다.
- 에디터와의 통합 : 에디터에서 구조체의 값을 수정할 수 있다.
- 네트워크 레플리케이션 : 구조체 자체는 레플리케이션 대상이 될 수 없지만 UPROPERTY로 지정한 변수는 레플리케이션이 될 수 있다.
- 블루프린트 통합 : 블루프린트에서 사용할 수 있게 된다.
USTRUCT 정의
USTRUCT([Specifier, Specifier, ...])
struct FStructName
{
GENERATED_BODY()
};
UCLASS와 유사하게 정의하고 이름 규칙 상으로 F로 시작해야 한다. 하지만 UPROPERTY만 사용할 수 있고 UFUNCTION은 사용할 수 없다. UPROPERTY를 사용하는 방법 또한 같고 마찮가지로 UObject를 가리킬 경우 UPROPERTY로 마킹을 하면 GC의 도움을 받을 수 있다. 공개 범위의 경우는 UCLASS 내부에서의 허용 범위와 USTRUCT 내부에서의 허용 범위가 모두 일치하면 접근 혹은 수정이 가능하다.
- UClass EditAnywhere : 모든 곳에서 EditAnywhere 수정 가능, 블루프린트에서만 EditDefaultsOnly 수정 가능, 인스턴스에서만 EditInstanceOnly 수정 가능
- UClass EditDefaulsOnly : 블루프린트에서 EditAnywhere, EditDefaultsOnly를 수정 가능
- UClass EditInstanceOnly : 인스턴스에서 EditAnywhere, EditInstanceOnly를 수정 가능
USTRUCT()
struct PLAYGROUND_API FTestStruct
{
GENERATED_BODY()
UPROPERTY(EditAnywhere)
int Anywhere = 3;
UPROPERTY(EditDefaultsOnly)
int DefaultsOnly = 2;
UPROPERTY(EditInstanceOnly)
int InstanceOnly = 1;
};
// ...
UPROPERTY(EditAnywhere)
FTestStruct EditAnywhereStuct;
UPROPERTY(EditDefaultsOnly)
FTestStruct EditDefaulsOnlyStruct;
UPROPERTY(EditInstanceOnly)
FTestStruct EditInstnaceOnlyStruct;
// ...
블루프린트
인스턴스
블루프린트 통합
블루프린트에 통합하기 위해서는 BlueprintType을 정의하면 되고 다음과 같은 효과가 있다.
- Blueprint에서 클래스의 BlueprintReadOnly, BlueprintReadWrite에 접근 가능
- Blueprint에서 변수로 선언 가능
- Make / Break 노드가 자동으로 생성됨
Make / Break
메타를 이용해서 직접 Make, Break를 사용할 수 있지만 기본적으로 Make, Break가 생성되서 활용할 수 있다. Make에서는 ReadWrite 변수가 노출되고 Break에서는 ReadWrite와 Readonly가 노출된다.
USTRUCT(BlueprintType)
struct FBlueprintReadWriteStruct
{
GENERATED_BODY()
// Make Node에서 노출
UPROPERTY(BlueprintReadWrite)
int BlueprintReadWrite = 1;
// Make, Break Node에서 노출
UPROPERTY(BlueprintReadOnly)
int BlueprintReadOnly = 2;
};
블루프린트 변수로 선언 가능
블루프린트 자체의 변수로도 선언하고 활용할 수 있다.
Class의 Property를 블루프린트에서 접근 가능하도록 설정 가능
UPROPERTY에서 BlueprintReadWrite, BluepirntReadOnly로 설정해서 블루프린트에서 접근 가능하도록 할 수 있다.
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FBlueprintStruct EditAnywhereBlueprintWriteStruct;
후속 학습
NoExport에 대해서 공부할 필요가 있다. NoExport는 리플렉션 코드를 작성하지 않는 대신 메타 데이터만 추가해주는 태그이다. 리플렉션이 필요 없거나 혹은 USTRUCT로 지정할 수 없을 때 블루프린트에 통합할 때 사용할 수 있다. 대표적으로는 FVector가 템플릿 구조체라서 USTRUCT를 사용할 수 없는데 NoExport를 이용해서 블루프린트에서 사용할 수 있도록 하고 있다. FVecotr의 대략적인 구조는 다음과 같다.
- MathFwd : 전방 선언, using FVecotr = UE::Math::TVector
- Vector.h : TVector 선언 및 정의
- NoExportTypes.h : Blueprint에서의 FVector 정의(NoExport)
- KismetMathLibray.inl : Blueprint에서의 Make, Break Vector를 정의
여기서 알 수 없는 부분은 블루프린트에서의 FVector가 어떻게 내부의 FVector로 변환되는 과정이다. 블루프린트 내부에서는 TVector를 생성해서 사용하고 있는 것 같은데 그 값이 어떻게 그대로 직렬화 되어서 에디터에서 표기 되는 것을 이해할 수 없다.
참고
'UnrealEngine' 카테고리의 다른 글
TObjectPtr (0) | 2025.01.23 |
---|---|
UInterface 정리 - 언리얼 오브젝트 매크로 5 (1) | 2025.01.20 |
UENUM 정리 - 언리얼 오브젝트 매크로 3 (2) | 2025.01.07 |
UFUNCTION 정리 - 언리얼 오브젝트 매크로 2 (2) | 2025.01.03 |
UPROPERTY 정리 - 언리얼 오브젝트 매크로 1 (2) | 2025.01.02 |