내배캠 TIL

[내배캠 TIL 260129] Unreal Cast는 무엇이고 왜 필요한가

xodn246 2026. 1. 29. 21:00

1. Cast의 정체

언리얼에서 사용하는 Cast<>는
형 변환이 아니라 런타임 타입 확인이다.

즉,

이 포인터가
정말로 내가 원하는 클래스 타입인지 확인하고
맞을 경우에만 해당 타입으로 사용하기 위한 도구다.


2. 왜 Cast가 필요한가

언리얼에서는 대부분의 객체를
AActor* 또는 UObject* 형태로 받는다.

AActor* Actor = ...;

이 상태에서는

  • Actor가 어떤 클래스인지 알 수 없고
  • AActor에 정의된 기능만 사용할 수 있다
Actor->Destroy();

하지만 특정 클래스에만 존재하는 함수는 호출할 수 없다.

Actor->DestroyAllSpawnedItems(); // 컴파일 에러

이때 필요한 것이 Cast다.


3. Cast의 기본 사용법

 
ASpawnVolume* Volume = Cast<ASpawnVolume>(Actor);

이 코드는 다음 의미를 가진다.

  • Actor가 실제로 ASpawnVolume 타입이면
    • ASpawnVolume 포인터를 반환
  • 그렇지 않으면
    • nullptr 반환

그래서 항상 다음과 같이 사용한다.

if (ASpawnVolume* Volume = Cast<ASpawnVolume>(Actor)) { Volume->DestroyAllSpawnedItems(); }

Cast 실패 시 if문에 들어가지 않으므로
크래시 없이 안전하게 처리할 수 있다.


4. Cast 성공과 실패의 기준

Cast는 포인터가 가리키는 객체의 실제 타입을 기준으로 판단한다.

AActor*
  - ASpawnVolume      Cast 성공
  - ACoinItem         Cast 실패
  - AEnemy            Cast 실패

포인터 변수의 타입이 아니라
실제 생성된 객체의 타입이 기준이다.


5. GetAllActorsOfClass와 Cast

UGameplayStatics::GetAllActorsOfClass(
    GetWorld(),
    ASpawnVolume::StaticClass(),
    FoundActors
);

이 경우 배열에는 SpawnVolume만 들어온다.

이론적으로는 Cast 없이 사용해도 된다.

for (AActor* Actor : FoundActors)
{
    Actor->DestroyAllSpawnedItems(); // 불가능
}

하지만 배열 타입이 AActor*이기 때문에
컴파일러는 해당 함수의 존재를 알 수 없다.

그래서 여전히 Cast가 필요하다.

 
for (AActor* Actor : FoundActors)
{
    if (ASpawnVolume* Volume = Cast<ASpawnVolume>(Actor))
    {
        Volume->DestroyAllSpawnedItems();
    }
}

6. Cast를 하지 않아도 되는 경우

이미 타입이 명확한 경우에는 Cast가 필요 없다.

ASpawnVolume* Volume = ...;
Volume->DestroyAllSpawnedItems();

또는

TArray<ASpawnVolume*> Volumes;

이 경우 컴파일 타임에 타입이 확정되어 있다.


7. C++ 캐스팅과의 차이

C 스타일 캐스트나 static_cast는
런타임 타입 검사를 하지 않는다.

ASpawnVolume* Volume = (ASpawnVolume*)Actor;

이 코드는
Actor가 실제로 SpawnVolume이 아닐 경우
즉시 크래시로 이어질 수 있다.

반면 언리얼의 Cast는
UObject 시스템을 사용해 타입을 검사한다.

  • 안전하다
  • 실패 시 nullptr 반환
  • 크래시 없음

8. Cast를 사용하는 기준 정리

  • AActor 또는 UObject로 받았다면 Cast 필요
  • 특정 클래스 전용 기능을 호출해야 한다면 Cast 필요
  • 이미 해당 클래스 포인터라면 Cast 불필요