[Unreal] 액터 라이프사이클(AActor Lifecycle)

김진우·2025년 7월 17일

Unreal

목록 보기
6/9
post-thumbnail


디스크에서 로드 (Load from Disk)

디스크에서 로드 경로는 UEngine::LoadMap이 호출되거나, 레벨 스트리밍이 UWorld::AddToWorld를 호출할 때처럼 레벨에 이미 존재하는 액터에 대해 실행 된다.

  1. 패키지/레벨에 있는 액터들이 디스크에서 로드된다.

  2. 직렬화된 액터는 디스크에서 로드를 완료한 후 PostLoad를 호출한다.
    사용자 버전 관리 및 수정 작업은 여기서 구현되어야 한다.
    PostLoadAActor::PostActorCreated와 상호 배타적이다.

  3. 월드는 UAISystemBase::InitializeActorsForPlay를 호출하여 액터들이 게임플레이를 시작할 수 있도록 준비한다.

  4. 레벨은 ULevel::RouteActorInitialize를 호출하여 초기화되지 않은 액터들과 심리스 트래블로 넘겨받은 액터들을 처리한다.

    4-1. AActor::PreInitializeComponents는 액터의 컴포넌트들에서 InitializeComponent가 호출되기 전에 실행된다.
    4-2. UActorComponent::InitializeComponent는 액터에 정의된 각 컴포넌트를 생성하기 위한 헬퍼 함수이다.
    4-3. AActor::PostInitializeComponents는 액터의 모든 컴포넌트가 초기화된 후 호출된다.

  5. 레벨이 시작되면 AActor::BeginPlay가 호출된다.

그림의 파란색 과정이다.


에디터에서 플레이 (Play in Editor)

Play in Editor 경로에서는, 액터를 액터를 디스크에서 로드하는 대신 에디터에서 복사한다. 복사된 액터는 "디스크에서 로드" 경로에 설명된 흐름과 유사하게 초기화 된다.

  1. 액터들이 에디터에서 새로운 월드로 복제된다.

  2. UObject::PostDuplicate 호출

  3. UAISystemBase::InitializeActorsForPlay 호출

  4. ULevel::RouteActorInitialize가 아직 초기화되지 않은 액터들에 대해 호출되며, 심리스 트래블(seamless travel) 중인 액터들도 처리한다.

    4-1. AActor::PreInitializeComponents는 액터의 컴포넌트들에서 InitializeComponent가 호출되기 전에 실행된다.
    4-2. UActorComponent::InitializeComponent는 액터에 정의된 각 컴포넌트를 생성하기 위한 헬퍼 함수이다.
    4-3. AActor::PostInitializeComponents는 액터의 모든 컴포넌트가 초기화된 후 호출된다.

  5. 레벨이 시작되면 AActor::BeginPlay가 호출된다.

그림의 노란색부터 초록색이 되기 전까지의 과정이다.


액터 생성 (Spawning)

액터(Actor)의 인스턴스를 생성(Spawn)할 때, 다음과 같은 순서로 함수들이 호출된다.

  1. UWorld::SpawnActor : 액터 스폰 시작
  2. AActor::PostSpawnInitialize : 액터가 월드에 생성된 이후 호출된다.
  3. AActor::PostActorCreated : 액터가 생성된 후 호출되며, 생성자에서 해야 할 초기화 코드는 이 함수에 구현해야 한다.
    • 이 함수는 PostLoad와 상호 배타적으로 호출된다.
  4. AActor::ExecuteConstruction : 액터의 생성 스크립트(예: 블루프린트의 Construction Script)가 실행된다.
  5. AActor::OnConstruction : 액터의 구성 작업이 진행된다.
    • 이 시점에 블루프린트 액터의 컴포넌트들이 생성되고, 변수들이 초기화된다.
  6. AActor::PostActorConstruction :
    6-1. AActor::PreInitializeComponents : 컴포넌트들의 InitializeComponent가 호출되기 전에 액터 레벨에서 호출된다.
    6-2. UActorComponent::InitializeComponent : 액터에 정의된 각 컴포넌트를 생성하고 초기화하는 헬퍼 이다.
    6-3. AActor::PostInitializeComponents : 모든 컴포넌트가 초기화된 후 호출된다.
  7. UWorld::OnActorSpawned : 월드에서 액터가 생성되었음을 알리는 브로드캐스트가 발생한다.
  8. AActor::BeginPlay : 게임 플레이가 시작되면 호출된다.

요악하면,
SpawnActor 호출 -> 액터 생성 -> 생성자 코드 실행 -> 생성 스크립트 실행(Construction Script) -> 액터 구성 작업 실행(컴포넌트, 변수) -> 모든 컴포넌트 초기화 -> 액터가 생성됨을 알리는 브로드캐스트 -> 액터 생성 종료
의 순서대로 액터가 생성된다.

그림의 하늘색 과정으로, 초록색 도형으로 넘어가기 전까지의 과정이다.


지연 생성 (Deferred Spawn)

액터(Actor)는 "Spawn 시 노출(Expose on Spawn)"로 설정된 속성이 있는 경우, 지연 생성(Deferred Spawn) 할 수 있다.

  1. UWorld::SpawnActorDeferred는 절차적으로 액터를 생성할 때 사용되며, 블루프린트 생성 스크립트가 실행되기 전에 추가 설정 작업을 할 수 있게

  2. SpawnActor에서 일어나는 기본적인 동작은 그대로 수행되지만, AActor::PostActorCreated 이후에 다음과 같은 절차가 이어진다.

    유효하지만 아직 완전히 초기화되지 않은 액터 인스턴스를 가지고 설정 작업 및 다양한 초기화 함수 호출을 할 수 있다.

    이후 AActor::FinishSpawning를 명시해 주면 생성 지연이 마무리 되고, AActor::ExecuteConstruction 이후의 과정으로 진행이 된다.

그림의 주황색 과정이다.


Lifecycle 종료 (End of Actor Lifecycle)

게임 플레이가 진행 중일 때 액터를 소멸하고 싶을 경우 수동으로 AActor::Destroy를 호출하면 된다.
액터의 Lifecycle 소멸 흐름을 보장하기 위해 AActor::EndPlay가 여러 곳에서 호출된다.

AActor::EndPlay가 호출되는 경우

  • Destroy 에 대한 명시적 호출
  • 에디터에서의 플레이가 종료된 경우
  • 레벨 트랜지션(seamless travel 또는 load map)
  • 액터가 포함된 스트리밍 레벨이 언로드될 때
  • 액터의 수명이 만료됨
  • 애플리케이션 종료(모든 액터가 소멸됨)

그림의 초록색 도형으로 넘어간 이후의 과정이다.


Garbage Collection

객체가 삭제 대상으로 표시 된 이후, 일정 시간이 지나면 가비지 컬렉션 이 해당 객체를 메모리에서 제거하고, 사용 중이던 리소스를 해제한다.

오브젝트의 소멸 중에 다음과 같은 함수가 호출된다.

  1. UObject::BeginDestroy

    • 객체가 메모리나 멀티스레드 리소스(예: 그래픽스 스레드에서 사용하는 프록시 객체 등)를 정리할 수 있는 첫 번째 함수이다.
    • 대부분의 게임플레이 관련 파괴 로직은 이보다 앞서 EndPlay 단계에서 처리되어야 한다.
  2. UObject::IsReadyForFinishDestroy

    • 가비지 컬렉션 프로세스가 이 함수를 호출하여 객체가 정말로 삭제될 준비가 되었는지 확인한다.
    • false를 반환하면, 실제 삭제는 다음 GC 패스까지 지연(Defer) 시킬 수 있다.
  3. UObject::FinishDestroy

    • 객체가 진짜로 삭제되기 직전에 호출된다.
    • 내부 자료구조를 해제할 수 있는 마지막 기회이다.
    • 이 호출 이후 객체의 메모리는 완전히 해제된다.

그림의 마지막 과정이다.


출처 - Actor Lifecycle

0개의 댓글