[언리얼 엔진] 액터의 수명 주기
- ⭐ Game Programming/Unreal Document
- 2021. 10. 9.
액터의 수명 주기
액터의 생성과 소멸에 대해 알아보자
수명 주기 분해도
디스크에서 로드
레벨에 배치되어있는 액터에 대해서, LoadMap이 발생하였을 때나 AddToWorld가 호출되었을때 발생한다.
- 패키지/레벨에 있는 액터가 디스크레엇 로드된다.
- PostLoad 이후 - 디스크에서의 로드 완료후 serialize된 액터에 의해 호출된다. PostLoad와 PostActorCreated는 상호 배제 된다.
- InitializeActorsForPlay 플레이용 액터 초기화
- RouteActorInitialize 액터 초기화 경로 변경 - 초기화 되지 않은 액터에 대해 호출
- PreInitializeComponents 컴포넌트 초기화 이전
- InitializeComponent 컴포넌트 초기화
- PostInitializeComponents 컴포넌트 초기화 이후
- BeginPlay 플레이 시작
에디터에서 플레이
액터를 디스크에서 로드하지않고 에디터에서 복사해온다.
- 에디터에 있는 액터를 새 월드로 복제한다.
- PostDuplicate 를 호출한다.
- InitializeActorsForPlay 플레이용 액터 초기화 호출
- 초기화되지 않은 액터는 RouteActorInitialize
- PreInitializeComponents 컴포넌트 초기화 이전
- InitializeComponent 컴포넌트 초기화
- PostInitializeComponents 컴포넌트 초기화 이후
- BeginPlay 플레이 시작
스폰
액터를 스폰할 때의 과정
- SpawnActor 호출
- PostSpawnInitialize 호출
- PostActorCreated 액터 생성 이후에 호출 PostActorCreated는 PostLoad와 상호배제적이다.
- ExecuteConstruction 생성 실행
- OnConstruction 생성시 액터의 생성 지점으로, 블루프린트 액터가 컴포넌트를 만들고 변수를 초기화
- PostActorConstruction 액터 생성 이후
- PreInitializeComponents 컴포넌트 초기화 이전
- InitializeComponent 컴포넌트 초기화
- PostInitializeComponents 컴포넌트 초기화 이후
- OnActorSpawned 액터 스폰시 UWorld에 브로드캐스팅 됨
- BeginPlay 플레이 시작
디퍼드 스폰
Expose On Spawn (스폰시 노출)로 설정된 프로퍼티가 있으면 액터는 디퍼드(유예시키고 나중에 한번에 몰아서) 스폰이 가능하다.
- SpawnActorDeferred 액터 디퍼드 스폰
- PostActorCreated 이후
- 유효하나 완료되지 않은 액터 인스턴스로 다양한 "초기화 함수"를 구성/호출 한다.
- FinishSpawning 액터 스폰 마머리 - 액터를 마무리 시키기 위해 호출된다. SpawnActor의 ExecuteConstruction 을 집는다.
수명의 마지막
액터 소멸(Destroy)은 여러가지 방식이 있지만, 끝은 항상 같다.
Destroy 소멸 - 수동으로 호출시 액터는 킬 대기 상태로 마킹되며 레벨의 액터 배열에서 제거
EndPlay 플레이 종료 - 액터의 수명이 끝났음을 보증하기 위해 호출된다. 플레이 도중에는 Destroy나 LevelTransition이나 레벨이 언로드 되면 호출된다. EndPlay가 호출되는 경우는 다음과 같다.
- Destroy 명시적 호출
- 에디터에서 플레이 종료
- Level Transition(심리스 트래블 또는 맵 로드)
- 액터가 들어있는 스트리밍 레벨 언로드
- 액터의 수명 만료
- 어플리케이션 종료 (모든 액터 소멸)
액터는 RF_PendingKill 마킹되어 다음 가비지 컬렉션 주기 동안 deallocate 된다. pendingkill(킬 대기 상태)를 검사하기 보다. FWeakObjectPtr 사용을 추천
OnDestroy 소멸시 - Destroy에 대한 구식 처리, EndPlay로 옮기자
가비지 컬렉션
오브젝트가 소멸 마킹된 이후, 가비지 컬렉션이 일어날 때 메모리에서 실제로 제거되어 리소스가 해제된다.
- BeginDestroy 소멸 시작 - 오브젝트 메모리 해제, 리소스 처리. 대부분의 함수들은 EndPlay에서 처리된다.
- IsReadyForFinishDestroy 소멸 마무리 준비 여부 - 가비지 컬렉션이 이 함수를 호출하여 오브젝트 할당을 해제할 준비가 되었는지 여부를 결정
- FinishDestroy 소멸 마무리 - 메모리 해제 이전 마지막 호출 함수
고급 가비지 컬렉션
언리얼 엔진의 가비지 컬렉션 프로세스는 모두 같이 소멸되는 오브젝트 클러스터를 만든다. 클러스터를 만들면 오브젝트를 개별적으로 삭제할 때에 비해 메모리 교란(churn)과 총 시간을 단축할 수 있다. 오브젝트가 로드되면서 서브오브젝트가 생성될 수 있다. 오브젝트와 서브오브젝트를 가비지 콜렉터의 단일 클러스터로 합쳐 넣을 경우, 엔진은 전체 오브젝트가 해제 준비될 때까지 클러스터에 사용되는 리소스의 해제를 지연시켰다가 모든 리소스를 한번에 해제 할 수 있다.
클러스터 작동 방식을 바꿔 효율을 향상 시킬수 있는 경우들은 다음과 같다.
- Clustering 클러스터링 - 이옵션은 끈다. 프로젝트 세팅에서 Garbage Collection 섹션 아래 Create Garbage Collector Uobject Clusters(가비지 콜렉터 오브젝트 클러스터 생성)옵션을 false로 설정하면 도니다. 대부분의 프로젝트의 경우 이 옵션을 끄면 가비지 컬렉션 효율이 떨어지므로 퍼포먼스 테스트를 통해 확인하도록 하자
- Cluster Merging 클러스터 병합 - 클러스터링이 true인경우 (프로젝트 세팅에서 Garbage Collection 섹션 아래) Merge GC Clusters(GC 클러스터 병합) 옵션을 true로 설정하면 클러스터 병합기능을 켤수 있다. 기본적으로 false이며 모든 프로젝트에 적합하지 않다. 오브젝트의 클러스터를 만드는 프로세스 도중 오브젝트를 검사하여 그안의 다른 오브젝트로의 레퍼런스를 찾을 수 있다.