UE5 - 액터의 라이프사이클
언리얼 엔진에서 제공하는 다양한 클래스들은 내부 GC(Garbage Collection)을 통해 메모리를 관리한다는 것을 지난 포스팅을 통해 알게되었습니다.
이에 추가적으로 레벨에 스폰된 액터가 언제 생성되며, 언제 사라지는지, 그리고 어떻게 더이상 사용하지 않는다 라고 판단하여 GC가 해당 액터를 소멸시키는지에 대해 조금 더 자세히 파악하고자 이번 포스팅을 작성하게 되었습니다.
이러한 이유로 UE5를 사용한 액터의 라이프사이클에 대해 알아보겠습니다.
액터 라이프사이클
액터 생성 단계 (Spawning)
- 디스크에서 로드하기 (Load Map / Add to World)
- 레벨을 변경하거나 불러올 시 언리얼 엔진 내부에서 호출되는 UnrealEngine::LoadMap이 발생하거나, UWorld::AddToWorld를 호출하는 경우같은, 이미 레벨에 있는 액터들에 대해 발생한다.
- 패키지/레벨에 있는 액터가 디스크에서 로드되는 단계
- 디스크에서 로드가 완료되면, 직렬화된 액터에서 PostLoad를 호출한다.
- 호출된 해당 액터의 컴포넌트가 초기화 된 후, 레벨이 시작될 때 해당 액터의 AActor::BeginPlay()가 호출된다.
- 에디터가 플레이 되는 경우 (Play in Editor)
- 에디터의 액터가 새 월드에 복제된다.
- UObject::PostDuplicate를 호출하여 해당 액터를 복제, 직렬화한다.
- 해당 액터에 정의된 각 컴포넌트를 생성, 초기화한다.
- 레벨이 시작될 때 AActor::BeginPlay()가 호출된다.
- 스폰 (Spawn Actor)
- 플레이를 위해 액터를 설정하기위해 호출된다.
- 월드에 스폰된 후 직렬화 및 액터 및 액터의 컴포넌트 생성 및 변수를 초기화 한다.
- 액터에 정의된 각 컴포넌트를 생성, 초기화, 호출한다.
- AActor::BeginPlay()를 통해 호출된다.
- 디퍼드 스폰 (Deferred Spawn)
- Expose On Spawn (스폰 시 노출)로 설정된 프로퍼티가 존재한다면, 해당 액터는 디퍼드 스폰이 가능하다.
- Deffered Spawn : 액터의 특정 설정을 초기화한 뒤, 활성화는 나중에 하는 방식.
- 특정 이벤트가 발생시 호출하는 액터 또는 성능최적화를 할 때 사용한다.
- Expose On Spawn (스폰 시 노출)로 설정된 프로퍼티가 존재한다면, 해당 액터는 디퍼드 스폰이 가능하다.
게임 실행 단계 (Game Play)
- 액터가 배치된 레벨 및 어플리케이션이 실행되고 있는 단계.
- 해당 액터가 매 Tick(프레임)마다 호출되는 단계
- 또는 데미지 처리와 같은 상태 업데이트를 하는 단계
- 언리얼 엔진 GC에서 해당 객체들을 Mark하여 메모리 해제를 방지한다.
액터 라이프사이클 종료 (End Play)
- Destory 함수에 대한 명시적 호출을 한다.
- 에디터에서 플레이가 종료된 경우
- 레벨 트랜지션 발생 시
- 액터의 수명이 만료될 경우
- 수명이 다해가는것을 보장하기 위해 언리얼 엔진 내부에서 해당 엑터의 EndPlay를 여러곳에서 호출하여 검증한다.
- 어플리케이션 종료 (모든 액터 소멸)
위와같이 라이프사이클 종료를 확인하기위해 여러개의 검증을 걸친 뒤, 액터를 더이상 사용하지 않는다 판단 할 시 액터는 내부에서 RF_PendingKill로 표시되어 언리얼 엔진이 해당 액터의 메모리 할당을 해제합니다.
※ EndPlay가 호출 되어도 트랜지션한 레벨에서 해당 액터가 사용된다면, 액터는 재사용 될 수 있다.
GC에 의한 오브젝트 제거 및 리소스 해제
- UObject::BeginDestroy : 오브젝트가 메모리를 해제하고, 게임 플레이가 아닌 기타 리소스들을 처리한다.
- UObject::IsReadyForFinishDestroy : 가비지 컬렉션에서 해당 오브젝트가 영구적으로 제거될 준비가 되었는지 확인하며, false 반환 시 다음 가비지컬렉션까지 소멸을 연기시킨다.
- UObject::FinishDestroy : 오브젝트가 실제로 소멸되며, 해당 함수 호출 뒤 메모리가 해제된다.
위의 4단계를 통해 액터가 생성되기에는 어떠한 방법이 있는지, 어떤 검증을 걸쳐 액터가 소멸된다고 판단하는지에 대해 알아보았습니다.
기존의 GC포스팅을 하였을 때 어떻게 엔진에서 소멸자를 담당하여 메모리를 효율적으로 사용하는지에 대해 알고 있었지만, 이번 포스팅을 통해 GC를 통해 마크 앤 스윕단계를 거치기 전에 액터의 생명주기를 알 수 있었습니다.