Unreal) TSubclassOf<>
TSubclassOf<>
란
특정 클래스의 하위 클래스(서브 클래스)만 참조 할 수 있도록 만들어주는 언리얼 엔진의 템플릿 클래스다.
일반적인 UClass*
포인터가 “어떤 클래스든 가리킬 수 있는 만능 포인터”라면, TSubclassOf<TBaseClass>
는 “오직 TBaseClass
를 상속받은 녀석들만 가리킬 수 있는 제한된 포인터” 이다.
왜 이런 제한이 필요하냐면, 타입 안정성에 큰 이점을 가진다.
TSubclassOf<>
의 필요성 (타입 안정성 확보)
코드를 작성할 때 가장 피하고 싶은 것 중 하나가 런타임 에러다.
특히 언리얼처럼 거대한 프레임워크에서는 작은 실수 하나가 전체 프로젝트에 영향을 미칠 수도 있다.
UClass*
를 사용하면 다음과 같은 문제가 발생할 수 있다.
// Bad Example: UClass* 사용 시
UPROPERTY(EditDefaultsOnly, Category=Gameplay)
UClass* MyActorClass; // 여기에 어떤 클래스든 할당 가능.
만약 MyActorClass
에 APawn
타입의 액터를 넣어야 하는데, 실수로 UTexture2D
같은 전혀 다른 클래스를 할당했다고 가정해 보면, 컴파일은 되겠지만, 나중에 이 MyActorClass
를 가지고 GetWorld()->SpawnActor(...)
를 호출하는 순간, 게임에 문제가 발생할 수 있다.
// Good Example: TSubclassOf<> 사용 시
UPROPERTY(EditDefaultsOnly, Category=Gameplay)
TSubclassOf<APawn> MyPawnClass; // 오직 APawn의 서브클래스만 할당 가능.
이렇게 선언하는 순간, 컴파일러가 강력한 가드 역할을 해준다.
MyPawnClass
에 APawn
이나 그 하위 클래스(예: AMyPlayerCharacter
, AEnemyAI
)가 아닌 다른 타입의 클래스를 할당하려고 하면, 컴파일 단계에서 바로 에러를 발생시킨다.
덕분에 런타임에 발생할 수 있는 잠재적인 버그를 미리 차단할 수 있다.
에디터와의 연동 (UPROPERTY)
TSubclassOf<>
의 진정한 가치는 UPROPERTY
매크로와 함께 사용할 때 발휘된다.
개발하다 보면 디자이너나 아티스트가 특정 클래스를 직접 선택해야 할 상황이 많다.
예를 들어, “이 발사체는 어떤 종류의 데미지를 줄 것인가?”와 같은 설정이 있겠다.
// UPROPERTY와 TSubclassOf<>의 시너지 효과
UPROPERTY(EditDefaultsOnly, Category=Damage)
TSubclassOf<UDamageType> DamageTypeClass;
이렇게 코드를 작성하고 언리얼 에디터를 열어보면, DamageTypeClass
프로퍼티의 드롭다운 목록에는 오직 UDamageType
을 상속받는 클래스들만 나타난다.
UDamageType_Fire
, UDamageType_Ice
, UDamageType_Poison
등, 우리가 정의해둔 정확한 데미지 타입 클래스들만 보이게 제한을 걸 수 있는 것이다.
디자이너/아티스트를 위한 이점
- 실수 방지: 불필요한 클래스가 목록에 표시되지 않으니, 실수로 엉뚱한 클래스를 선택할 위험이 줄어든다.
- 작업 효율 증대: 수많은 클래스 중에서 일일이 찾아 헤맬 필요 없이, 필요한 클래스만 필터링되어 보이므로 작업 속도가 향상된다.
- 명확한 의도: “이 필드에는
UDamageType
만 들어갈 수 있어.”라는 개발자의 의도가 에디터에도 명확하게 전달된다.
TSubclassOf<>
의 활용 예시
TSubclassOf<>
는 특정 클래스의 인스턴스가 아니라, 클래스 자체의 타입 정보를 다룰 때 사용된다.
주로 다음과 같은 상황에서 유용하게 활용.
- 액터/오브젝트 스폰 시:
GetWorld()->SpawnActor<AMyActor>(MyActorClass, ...);
와 같이 특정 타입의 액터를 런타임에 생성할 때, 어떤 클래스를 스폰할지 참조할 때 사용.
- 기본 속성 (CDO) 접근:
- 특정 클래스의 Class Default Object (CDO)에 접근하여, 해당 클래스의 기본 설정값을 읽어올 때 유용.
- 팩토리 패턴 구현 시:
- 다양한 종류의 아이템이나 오브젝트를 생성하는 팩토리 클래스를 만들 때, 어떤 아이템을 생성할지 클래스 타입을 저장하는 용도로 활용.
댓글남기기