0. 서문
이 글을 읽기에 앞서, UE4의 Reflection에 대한 이해가 없다면, 꼭 아래 문서부터 읽도록 하자.
몇몇 기억해야 할 것들만 추려보면 다음과 같다.
1) 클래스 추가하기
엔진과 관련없는 구현체가 아닌 경우엔, C++ 클래스 마법사를 통해서 클래스를 생성하라.
Unreal Header Tool (UHT)가 엔진과 에디터에서 필요한 구성 모두를 자동으로 만들어 준다.
- #include "ClassName.generated.h" 생성 및 자동 포함
- UCLASS(...) 매크로 및 GENERATED_BODY() 매크로 자동 포함
- 필요시 ModuleName_API 자동 포함 (게임플레이 모듈 참고)
1번과 2번의 내용은 "ClassName.generated.h" 헤더와 "ObjectMacros.h" 파일을 열어보면, 해당 매크로들에 의해 대략 어떠한 코드들이 생성되는지 알 수 있다.
- 복사, 이동 생성자 금지
- RTTI 메타 데이터 생성
- Reflection 메타 데이터 생성 (StaticClass() 같은...)
- Super, ThisClass 키워드(typedef) 생성
- new 할당자 정의
- FArchive로의 Serialize 함수 정의(operator <<)
- 기타 등등
개별 항목들에 대해서 모두 자세히 기술하기엔, 이 문서의 본디 의도와는 거리가 있으므로 이쯤에서 생략토록 한다.
2) 클래스 선언
클래스 선언에는 이름, 상속 관계 표시, 그리고 엔진 및 에디터 전용 기능을 위한 UCLASS specifier와 meta 지정이 있으며 형식은 다음과 같다.
위에서도 얘기했듯이, C++ 클래스 마법사를 통하면 빈 클래스를 상속받는 경우가 아니라면 아래와 같은 기본 형식을 가진다.
#include "ClassName.generated.h"
UCLASS([specifier, specifier, ...], [meta(key=value, key=value, ...)])
class ClassName : public ParentName
{
GENERATED_BODY()
// ...
}
이후 문서엔 자주 사용되는 specifier 위주로만 조금 더 자세히 정리하였다.
(UCLASS specifier 열거값들은 ObjectMacro.h의 namespace UC에서 확인할 수 있다)
2. Abstract
해당 클래스가 추상 클래스임을 나타내는 지정자이다.
당연하게도 인스턴스를 생성하지 못하며, 에디터 상에 그 자체로 추가될 수 없다.
엔진에 미리 정의된 클래스 중에선, 대표적으로 AActor 클래스가 추상 클래스이다.
UCLASS(abstract)
class ENGINE_API AActor : public UObject
{
...
}
3. Config=iniName
해당 클래스가 환경설정(*.ini) 파일에 데이터를 저장할 수 있음을 나타내는 지정자이다.
클래스 멤버 변수 중 config/globalconfig 지정자를 가지는 변수가 있을 경우, 그 변수가 (...) 사이에 지정된 환경설정 파일에 저장되도록 해 준다.
이 지정자는 모든 자식 클래스에 전파되며 무시될 수 없으나, 자식 클래스에서 config 지정자에 다른 파일 이름을 지정하는 식으로 재정의하여 저장될 ini 파일을 변경할 수는 있다.
데이터를 저장할 .ini 파일명은 게임 이름에서 "Game"을 뺀 다음 IniName을 덧붙인 형식을 가진다.
(UDKGame에서 config=Camera라면, UDKCamera.ini를 사용하게 된다)
다음 네 개의 ini는 기본적으로 존재하는 것들이다.
- Config=Engine
- Config=Editor
- Config=Game
- Config=Input
4. MinimalAPI
클래스의 형식 정보만 다른 모듈에서 사용할 수 있게뜸 export 하도록 하는 지정자이다.
즉, 해당 클래스로 형 변환은 가능하지만, 해당 클래스의 함수는 호출이 불가능하다 (inline 메쏘드는 제외)
다른 모듈에서 모든 함수를 접근하도록 할 필요가 없는 클래스의 경우 export 타임이 단축된다.
대표적인 예가, GameMode 클래스라 할 수 있다.
UCLASS(minimalapi)
class ABatteryCollectorGameMode : public AGameModeBase
{
GENERATED_BODY()
// ...
};
5. DependsOn=(ClassName, ...)
해당 클래스보다 먼저 컴파일되어야 할 클래스들의 이름을 다음과 같은 두 형식으로 지정할 수 있다.
// 1. 1 DependsOn + multiple target class
UCLASS(DependsOn=(Head, Arm, Leg))
class Body
{
GENERATED_BODY()
// ...
};
// 2. Multiple DependsOn
UCLASS(DependsOn=Head, DependsOn=Arm, DependsOn=Leg)
class Body
{
GENERATED_BODY()
// ...
};
6. within=(ClassName)
이 클래스의 객체(오브젝트)가 ClassName의 외부에서는 생성되거나 존재할 수 없음을 의미한다.
이 클래스의 객체를 생성하기 위해서는 ClassName이 Outer Object로 지정되어야 한다.
즉, "이 클래스는 ClassName만 Has 할 수 있다"는 뜻.
///////////////////////////////////////////////////////////////////////////////////////////////
// UStrategyCheatManager + within=StrategyPlayerController
///////////////////////////////////////////////////////////////////////////////////////////////
UCLASS(Within=StrategyPlayerController)
class UStrategyCheatManager : public UCheatManager
{
GENERATED_UCLASS_BODY()
/**
* Give the player gold.
*
* @param NewGold The amount of gold to add to the players gold.
*/
UFUNCTION(exec)
void AddGold(uint32 NewGold);
};
///////////////////////////////////////////////////////////////////////////////////////////////
// AStrategyPlayerController header
///////////////////////////////////////////////////////////////////////////////////////////////
/** Class of my CheatManager. The Cheat Manager is not created in shipping builds */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Cheat Manager")
TSubclassOf<class UCheatManager> CheatClass;
///////////////////////////////////////////////////////////////////////////////////////////////
// AStrategyPlayerController cpp
///////////////////////////////////////////////////////////////////////////////////////////////
AStrategyPlayerController::AStrategyPlayerController(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
, bIgnoreInput(false)
{
CheatClass = UStrategyCheatManager::StaticClass();
PrimaryActorTick.bCanEverTick = true;
bHidden = false;
bShowMouseCursor = true;
}
7. Blueprintable / BlueprintType
Blueprintable은 해당 클래스가 블루프린트 생성시 부모 클래스로써 노출시키는 지정자이다.
즉, 이 지정자가 붙어 있는 C++ 클래스로부터 Blueprint 파생 클래스를 생성시켜 확장시킬 수 있다.
특별히 Blueprintable 지정자를 선언하지 않으면, 기본 설정은 Non-Blueprintable 이다.
BlueprintType은 해당 클래스를 블루프린트의 변수로 사용할 수 있는 형식으로 노출시키는 지정자이다.
'UE4' 카테고리의 다른 글
[UE4] World 내 Object/Actor 순회 (0) | 2023.04.24 |
---|---|
[UE4] MyLogMacro.h (0) | 2023.04.24 |
[UE4] 프로퍼티 및 UPROPERTY 주요 지정자 (0) | 2023.04.24 |
[UE4] 함수 및 UFUNCTION 주요 지정자 (0) | 2023.04.24 |
[UE4] Garbage Collection overview (0) | 2023.04.24 |