KoreanFoodie's Study

[언리얼] 효율적인 클래스 타입 체크 방법 (런타임) 본문

Game Dev/Unreal C++ : Dev Log

[언리얼] 효율적인 클래스 타입 체크 방법 (런타임)

GoldGiver 2023. 1. 13. 15:13

UObject 의 클래스 타입 체크 (런타임)

우리가 아이템을 사용하는데, 소모품일 경우 수량을 깎는 코드를 짠다고 가정해 보자. 코드는 다음과 같다.

if (nullptr != Cast<FConsumable>(myItem))
{
    this->consumeItem(myItem);
}
else
{
    this->useItem(myItem);
}

(물론 현실적으로 이런 경우, FConsumable 클래스에서 useItem 을 override 하겠지만.. 여튼)

위처럼, 객체의 클래스 타입을 체크하는 경우, 어떻게 하는 것이 효율적일까?

 

위와 같은 경우에, 만약 캐스팅이 실제로 필요한 경우가 아니라면(즉, 그냥 타입 체킹만 하면 되는 경우라면), Cast(언리얼의 Cast 는 업/다운 캐스팅을 할 수 있도록 구현되어 있다)를 쓰는 것보다, IsA 를 활용하는 것이 더 효율적이다.

if (myItem->IsA(FConsumable::StaticClass()))
{
    this->consumeItem(myItem);
}
else
{
    this->useItem(myItem);
}

그리고 Cast 를 실제로 해야 하는 경우에는, CastChecked 를 호출해도 된다. CastChecked 를 이용하면 내부적으로 IsA 를 사용하는 과정을 생략할 수 있다(생략을 위해서는 DO_CHECK 이 꺼져 있어야 하는데, development build 에서는 1로 세팅이 되어 있고, shipping build 에서는 0으로 되어 있다. 이때의 값은 USE_CHECKS_IN_SHIPPING임).

 

간단한 타입의 경우에는, 그냥 static_cast 를 사용해서 타입 유효성을 컴파일 타임에 체크하자.

 

 

UClass 의 클래스 타입 체크

그런데 위에서 사용한 IsA 는 UObject 에 유용한 방식이다. UClass 변수의 경우에는, IsChildOf 를 사용하자!

bool bIsDerivedFromB = ClassA->IsChildOf(ClassB);

if (bIsDerivedFromB)
{
    UE_LOG(LogTemp, Display, TEXT("ClassA is derived from ClassB"));
}
else
{
    UE_LOG(LogTemp, Display, TEXT("ClassA is not derived from ClassB"));
}

위 답변은 사실... ChatGPT 가 만들어낸 것이다 😅

 

참고 : 언리얼 포럼
Comments