언리얼 엔진에서 제공하는 다양한 클래스들은 내부 GC(Garbage Collection)을 통해 메모리를 관리한다는 것을 지난 포스팅을 통해 알게되었습니다.

UE5 - Garbage Collection 

 

이에 추가적으로 레벨에 스폰된 액터가 언제 생성되며, 언제 사라지는지, 그리고 어떻게 더이상 사용하지 않는다 라고 판단하여 GC가 해당 액터를 소멸시키는지에 대해 조금 더 자세히 파악하고자 이번 포스팅을 작성하게 되었습니다.

이러한 이유로 UE5를 사용한 액터의 라이프사이클에 대해 알아보겠습니다.

 

액터 라이프사이클 분해도 - https://dev.epicgames.com/documentation/ko-kr/unreal-engine/unreal-engine-actor-lifecycle

 

액터 라이프사이클

 

액터 생성 단계 (Spawning)

  1. 디스크에서 로드하기 (Load Map / Add to World)
    • 레벨을 변경하거나 불러올 시 언리얼 엔진 내부에서 호출되는 UnrealEngine::LoadMap이 발생하거나, UWorld::AddToWorld를 호출하는 경우같은, 이미 레벨에 있는 액터들에 대해 발생한다.
    • 패키지/레벨에 있는 액터가 디스크에서 로드되는 단계
    • 디스크에서 로드가 완료되면, 직렬화된 액터에서 PostLoad를 호출한다.
    • 호출된 해당 액터의 컴포넌트가 초기화 된 후, 레벨이 시작될 때 해당 액터의 AActor::BeginPlay()가 호출된다.
  2. 에디터가 플레이 되는 경우 (Play in Editor)
    • 에디터의 액터가 새 월드에 복제된다.
    • UObject::PostDuplicate를 호출하여 해당 액터를 복제, 직렬화한다.
    • 해당 액터에 정의된 각 컴포넌트를 생성, 초기화한다.
    • 레벨이 시작될 때 AActor::BeginPlay()가 호출된다.
  3. 스폰 (Spawn Actor)
    • 플레이를 위해 액터를 설정하기위해 호출된다.
    • 월드에 스폰된 후 직렬화 및 액터 및 액터의 컴포넌트 생성 및 변수를 초기화 한다.
    • 액터에 정의된 각 컴포넌트를 생성, 초기화, 호출한다.
    • AActor::BeginPlay()를 통해 호출된다.
  4. 디퍼드 스폰 (Deferred Spawn)
    • Expose On Spawn (스폰 시 노출)로 설정된 프로퍼티가 존재한다면, 해당 액터는 디퍼드 스폰이 가능하다.
      • Deffered Spawn : 액터의 특정 설정을 초기화한 뒤, 활성화는 나중에 하는 방식.
      • 특정 이벤트가 발생시 호출하는 액터 또는 성능최적화를 할 때 사용한다.

 

게임 실행 단계 (Game Play)

  • 액터가 배치된 레벨 및 어플리케이션이 실행되고 있는 단계.
  • 해당 액터가 매 Tick(프레임)마다 호출되는 단계
  • 또는 데미지 처리와 같은 상태 업데이트를 하는 단계
  • 언리얼 엔진 GC에서 해당 객체들을 Mark하여 메모리 해제를 방지한다. 

 

액터 라이프사이클 종료 (End Play)

  • Destory 함수에 대한 명시적 호출을 한다.
  • 에디터에서 플레이가 종료된 경우
  • 레벨 트랜지션 발생 시
  • 액터의 수명이 만료될 경우
    • 수명이 다해가는것을 보장하기 위해 언리얼 엔진 내부에서 해당 엑터의 EndPlay를 여러곳에서 호출하여 검증한다. 
  • 어플리케이션 종료 (모든 액터 소멸)

위와같이 라이프사이클 종료를 확인하기위해 여러개의 검증을 걸친 뒤, 액터를 더이상 사용하지 않는다 판단 할 시 액터는 내부에서 RF_PendingKill로 표시되어 언리얼 엔진이 해당 액터의 메모리 할당을 해제합니다.

 

※ EndPlay가 호출 되어도 트랜지션한 레벨에서 해당 액터가 사용된다면, 액터는 재사용 될 수 있다.

 

GC에 의한 오브젝트 제거 및 리소스 해제

  • UObject::BeginDestroy : 오브젝트가 메모리를 해제하고, 게임 플레이가 아닌 기타 리소스들을 처리한다.
  • UObject::IsReadyForFinishDestroy : 가비지 컬렉션에서 해당 오브젝트가 영구적으로 제거될 준비가 되었는지 확인하며, false 반환 시 다음 가비지컬렉션까지 소멸을 연기시킨다.
  • UObject::FinishDestroy : 오브젝트가 실제로 소멸되며, 해당 함수 호출 뒤 메모리가 해제된다.

 

 

위의 4단계를 통해 액터가 생성되기에는 어떠한 방법이 있는지, 어떤 검증을 걸쳐 액터가 소멸된다고 판단하는지에 대해 알아보았습니다.

기존의 GC포스팅을 하였을 때 어떻게 엔진에서 소멸자를 담당하여 메모리를 효율적으로 사용하는지에 대해 알고 있었지만, 이번 포스팅을 통해 GC를 통해 마크 앤 스윕단계를 거치기 전에 액터의 생명주기를 알 수 있었습니다.

 


 

https://dev.epicgames.com/documentation/ko-kr/unreal-engine/unreal-engine-actor-lifecycle#%EC%95%A1%ED%84%B0%EB%9D%BC%EC%9D%B4%ED%94%84%EC%82%AC%EC%9D%B4%ED%81%B4%EC%A2%85%EB%A3%8C

+ Recent posts