icon
2장 : 언리얼 C++ 기초

AActor와 UObject의 차이점


지난 절에서는 언리얼 엔진 C++의 핵심인 반사 시스템과 이를 위한 UCLASS, UPROPERTY, UFUNCTION 매크로에 대해 알아보았습니다. 이제 여러분이 앞으로 언리얼 엔진에서 C++ 코드를 작성할 때 가장 많이 마주하게 될 두 가지 기본 클래스, 바로 UObjectAActor 에 대해 깊이 있게 이해하는 시간을 가질 겁니다. 이 두 클래스의 차이점을 명확히 아는 것은 언리얼 엔진의 객체 시스템을 이해하는 데 매우 중요합니다.


UObject: 언리얼 객체 시스템의 심장

먼저 UObject 에 대해 이야기해볼까요? UObject는 언리얼 엔진의 모든 객체 지향 프로그래밍의 가장 기본적인 조상 클래스입니다. 언리얼 엔진에서 '객체'라고 불리는 거의 모든 것(액터, 컴포넌트, 에셋, 게임 모드 등)은 직간접적으로 UObject를 상속받습니다. UObject가 담당하는 핵심적인 역할들은 다음과 같습니다.

  • 반사 시스템 통합: UObject는 앞서 배운 UCLASS, UPROPERTY, UFUNCTION 매크로를 통해 언리얼 엔진의 반사 시스템에 통합됩니다. 덕분에 UObject를 상속받은 모든 클래스는 에디터에서 속성을 조작하고, 블루프린트와 연동되며, 저장 및 로드될 수 있습니다.
  • 가비지 컬렉션(Garbage Collection) 관리: C++에서 메모리 관리는 개발자에게 큰 부담이 될 수 있습니다. 하지만 UObject는 언리얼 엔진의 자체 가비지 컬렉터에 의해 자동으로 메모리 수명 주기가 관리됩니다. 여러분이 UObject를 상속받은 객체를 생성하면, 언리얼 엔진은 더 이상 참조되지 않는 객체를 자동으로 감지하고 메모리를 해제합니다. 이는 메모리 누수를 방지하고 개발 편의성을 크게 높여줍니다.
  • 직렬화(Serialization): UObject는 자신과 자신의 속성들을 저장하고 불러올 수 있는 직렬화 기능을 제공합니다. 이는 게임 상태를 저장하거나, 네트워크를 통해 객체 데이터를 전송할 때 매우 유용합니다.
  • 에디터 통합: UObject 기반의 객체들은 언리얼 에디터에 통합되어 콘텐츠 브라우저에 표시되거나, 디테일 패널에서 속성을 편집할 수 있게 됩니다.
  • 이름 관리 및 참조: UObject는 엔진 내에서 고유한 이름을 가질 수 있으며, 다른 UObject들을 강력하게 참조할 수 있는 메커니즘을 제공합니다.

간단히 말해, UObject는 언리얼 엔진의 스마트한 객체 시스템에 편입되어 엔진의 다양한 관리 기능(메모리, 직렬화, 반사 등)의 혜택을 받을 수 있도록 해주는 최소 단위의 클래스입니다. 여러분이 만드는 커스텀 데이터 구조체나 관리자 클래스 등이 게임 월드에 직접 배치되지 않으면서도 엔진의 관리가 필요한 경우, UObject를 상속받아 사용하게 됩니다.


AActor: 월드에 존재할 수 있는 모든 것

그렇다면 AActor 는 무엇일까요? AActor는 이름에서 알 수 있듯이, 언리얼 엔진의 3D 게임 월드(Level)에 배치될 수 있는 모든 객체의 기본 클래스입니다. 즉, 여러분이 게임 화면에서 보거나 상호작용할 수 있는 거의 모든 것들(캐릭터, 카메라, 라이트, 스폰 지점, 트리, 건물 등)은 AActor를 상속받습니다.

AActorUObject를 상속받습니다. 이는 AActorUObject의 모든 기능을 그대로 물려받는다는 의미입니다. 즉, AActor도 가비지 컬렉션의 대상이 되고, 직렬화되며, 에디터에 노출됩니다. 하지만 AActorUObject에는 없는 추가적인 중요한 기능들을 제공합니다.

  • 변환(Transform) 정보: AActor는 3D 월드에서 자신의 위치(Location), 회전(Rotation), 크기(Scale) 정보를 가집니다. 이 정보들을 통해 액터가 3D 공간의 어디에 어떻게 존재하는지 정의됩니다.
  • 컴포넌트(Components) 컨테이너: AActorUActorComponent를 상속받는 여러 컴포넌트들을 부착하여 자신의 기능을 확장할 수 있는 컨테이너 역할을 합니다. 예를 들어, StaticMeshComponent는 액터에 시각적인 3D 모델을 부여하고, CapsuleComponent는 충돌 영역을, MovementComponent는 이동 기능을 제공합니다. 액터는 이 컴포넌트들을 조합하여 복잡한 역할을 수행합니다.
  • 수명 주기 관리: AActorBeginPlay(), Tick(), EndPlay() 등 게임 월드 내에서의 특정 이벤트 발생 시 호출되는 중요한 수명 주기 함수들을 가집니다. 여러분은 이 함수들을 오버라이드(Override)하여 액터의 동작을 정의하게 됩니다.
  • 네트워크 복제(Networking Replication): 멀티플레이어 게임을 만들 때, AActor는 네트워크를 통해 자신의 상태를 클라이언트들에게 복제하는 기능을 제공합니다.
  • 콜리전(Collision) 및 물리 시뮬레이션: 액터는 자체적으로 또는 컴포넌트를 통해 다른 액터들과의 충돌을 감지하고, 물리 시뮬레이션에 참여할 수 있습니다.

핵심 차이점 요약: "월드에 존재하느냐?"

가장 핵심적인 차이점을 한 문장으로 요약하자면 이렇습니다:

  • UObject: 언리얼 엔진의 객체 시스템에 편입되어 엔진의 관리를 받는 일반적인 객체입니다. 하지만 3D 월드에 직접적으로 배치되거나 시각적으로 나타나지 않습니다.
  • AActor: UObject를 상속받아 UObject의 모든 기능을 가지면서, 3D 게임 월드에 배치될 수 있는 특별한 객체입니다. 위치, 회전, 스케일과 같은 변환 정보를 가지며, 컴포넌트들을 통해 다양한 시각적/물리적/논리적 기능을 수행합니다.
특징UObjectAActor
기본 조상언리얼 엔진 모든 객체의 최상위 클래스UObject를 상속받음
월드 존재3D 월드에 직접 배치되지 않음3D 월드에 직접 배치 가능 (위치, 회전, 스케일 가짐)
용도데이터 컨테이너, 관리자, 에셋 등게임 월드 내의 플레이어, 적, 환경 오브젝트, 라이트 등
컴포넌트가질 수 없음 (정확히는 UActorComponent 아님)UActorComponent를 상속받는 컴포넌트들을 가질 수 있음
수명 주기주로 가비지 컬렉터에 의해 관리BeginPlay, Tick, EndPlay 등 월드 이벤트와 연동됨

언제 무엇을 사용할까?

  • AActor를 상속받을 때

    • 게임 월드에 시각적으로 배치되어야 하는 오브젝트 (예: 캐릭터, 건물, 무기, 차량, 조명).
    • 3D 공간에서 위치, 회전, 스케일 정보를 가져야 하는 오브젝트.
    • 다른 컴포넌트를 부착하여 복합적인 기능을 수행해야 하는 오브젝트.
    • 특정 게임 이벤트(예: 충돌, 트리거)에 반응해야 하는 오브젝트.
  • UObject를 상속받을 때

    • 게임 월드에 직접 배치될 필요는 없지만, 엔진의 가비지 컬렉션이나 직렬화의 혜택을 받고 싶은 데이터 컨테이너.
    • 특정 시스템의 관리자 클래스 (예: 인벤토리 관리자, 퀘스트 관리자).
    • 특정 UI 위젯의 데이터 모델.
    • 블루프린트에서 접근하고 싶은 커스텀 데이터 구조체.
    • UActorComponent를 상속받지 않는 순수 논리적 컴포넌트.

이러한 이해를 바탕으로 여러분은 언리얼 엔진 프로젝트에서 어떤 상황에 어떤 기본 클래스를 상속받아 사용할지 올바른 결정을 내릴 수 있게 될 것입니다. 다음 절에서는 이 지식을 활용하여 AActor를 상속받는 여러분의 첫 번째 C++ 클래스를 직접 생성하고 코드를 작성하는 실습을 진행할 것입니다. 개념을 실제 코드로 옮겨보는 과정이 훨씬 명확한 이해를 가져다줄 거예요!