본문 바로가기
Unreal/Manual

Unreal 액터(Actor)의 생명 주기(Life Cycle)

by Dev_카페인 2023. 12. 10.
반응형

[Unreal] 액터(Actor)의 생명 주기(Life Cycle)

 

 

Actor Lifecycle

What actually happens when an Actor is loaded or spawned, and eventually dies.

docs.unrealengine.com

 

이 문서는 다음을 포함하는 Actor 의 수명 주기에 대한 높은 수준의 개요입니다 .

  • 액터 초기화 방법을 포함하여 액터가 레벨에 인스턴스화되거나 스폰되는 방법입니다.
  • 액터가 PendingKill로 표시된 후 가비지 컬렉션을 통해 제거되거나 파괴되는 방식입니다.
  • 아래 흐름도는 액터 인스턴스화 방법에 대한 주요 경로를 보여줍니다. 액터가 어떻게 생성되든, 모두 소멸될 때까지 같은 경로를 따릅니다.

 

 

디스크에서 로드

Load From Disk 경로는 UEngine::LoadMap이 발생하거나 레벨 스트리밍이 UWorld::AddToWorld를 호출할 때처럼 이미 레벨에 있는 모든 액터에 대해 발생합니다 .

1. 패키지/레벨의 액터는 디스크에서 로드됩니다.
2. 직렬화된 Actor는 디스크에서 로드가 완료된 후 PostLoad를 호출합니다. 모든 사용자 정의 버전 관리 및 수정 동작은 여기에서 구현되어야 합니다. PostLoad는 AActor::PostActorCreated 와 상호 배타적입니다 .
3. 세계는 UAISystemBase::InitializeActorsForPlay를 호출하여 액터가 게임플레이를 시작할 수 있도록 준비합니다.
4. 레벨은 초기화되지 않은 액터와 원활한 이동에 대해 ULevel::RouteActorInitialize를 호출합니다.

  • AActor::PreInitializeComponents 는 액터의 컴포넌트에서 초기화 구성요소가 호출되기 전에 호출됩니다.
  • UActorComponent::InitializeComponent는 액터에 정의된 각 컴포넌트 생성을 위한 도우미 함수입니다.
  • AActor::PostInitializeComponents 는 액터의 컴포넌트가 초기화된 후에 호출됩니다.

5. AActor::BeginPlay 는 레벨이 시작될 때 호출됩니다.


에디터에서 플레이

에디터에서 플레이 경로에서 액터는 디스크에서 로드되는 대신 에디터에서 복사됩니다. 그런 다음 복사된 액터는 디스크에서 로드 경로에 설명된 흐름과 유사하게 초기화됩니다.

1. 에디터의 액터는 새로운 월드에 복제됩니다.
2. UObject::PostDuplicate 가 호출됩니다.
3. UAISystemBase::InitializeActorsForPlay
4. ULevel::RouteActor 초기화되지 않은 액터에 대해 초기화하고 원활한 이동을 포함합니다.

  • AActor::PreInitializeComponents 는 액터의 컴포넌트에서 초기화 구성요소가 호출되기 전에 호출됩니다.
  • UActorComponent::InitializeComponent는 액터에 정의된 각 컴포넌트 생성을 위한 도우미 함수입니다.
  • AActor::PostInitializeComponents 는 액터의 컴포넌트가 초기화된 후에 호출됩니다.

5. AActor::BeginPlay 는 레벨이 시작될 때 호출됩니다.


산란

액터 인스턴스를 생성할 때 따라야 할 경로는 다음과 같습니다:

1. UWorld::SpawnActor 가 호출됩니다.
2. AActor::PostSpawnInitialize 는 액터가 월드에 스폰된 후에 호출됩니다.
3. AActor::PostActorCreated 는 스폰된 액터 생성 후 호출되며, 모든 생성자 구현 동작이 여기에 있어야 합니다.
    PostActorCreated는 PostLoad 와 상호 배타적입니다.
4. AActor::ExecuteConstruction :
5. AActor::OnConstruction - 액터 구성으로, 블루프린트 액터의 구성요소가 생성되고 블루프린트 변수가 초기화되는 곳입니다.
6. AActor::PostActorConstruction :

  • AActor::PreInitializeComponents 액터의 컴포넌트에서 초기화 구성 요소가 호출되기 전에 호출됩니다.
  • UActorComponent::InitializeComponent는 액터에 정의된 각 컴포넌트 생성을 위한 도우미 함수입니다.
  • AActor::PostInitializeComponents 는 액터의 컴포넌트가 초기화된 후에 호출됩니다.

7. UWorld::OnActorSpawned는 UWorld에서 방송됩니다.
8. AActor::BeginPlay 가 호출됩니다.


지연된 생성

액터는 속성을 "스폰 시 노출"로 설정하여 스폰을 연기할 수 있습니다.
1. UWorld::SpawnActorDeferred 는 절차적 액터를 생성하기 위한 것이며, 블루프린트 구성 스크립트 전에 추가 설정을 허용합니다.
2. SpawnActor의 모든 것은 발생하지만 AActor::PostActorCreated 이후에는 다음이 발생합니다:

  • 유효하지만 불완전한 Actor 인스턴스를 사용하여 다양한 "초기화 함수"를 설정하고 호출하세요.
  • AActor::FinishSpawning은 액터 마무리를 위해 호출되며,Spawn Actor 라인의 AActor::ExecuteConstruction 에서 선택됩니다.


액터 수명주기 종료

여러 가지 방법으로 액터를 파괴할 수 있지만, 월드에서 제거되는 방식도 같은 방법을 따릅니다. 게임 플레이 중에 아래 함수를 호출할 수 있지만, 플레이 중에 실제로 파괴되지 않는 액터가 많기 때문에 완전히 선택 사항입니다(가비지 수집 참조).

 

  • AActor::Destroy는 액터를 제거하려고 했지만 게임플레이가 계속 진행 중일 때마다 게임에서 수동으로 호출됩니다. 액터는 보류 중인 킬로 표시되고 레벨의 액터 배열에서 제거됩니다.
  • AActor::EndPlay는 액터의 수명이 끝나가는 것을 보장하기 위해 여러 곳에서 호출됩니다. 플레이 도중 액터가 포함된 스트리밍 레벨이 언로드되면 Destroy는 이 메서드와 레벨 전환을 호출합니다.
  • EndPlay는 다음에서 호출됩니다.
    • Destroy에 대한 명시적인 호출입니다.
    • Editor에서 플레이가 종료되었을 때.
    • 레벨 전환(원활한 이동 또는 로드 맵).
    • 액터가 포함된 스트리밍 레벨이 언로드됩니다.
    • Actor의 수명이 만료되었습니다.
    • 애플리케이션이 종료됩니다(모든 액터가 파괴됨).

이런 일이 어떻게 발생하든 액터는 RF_PendingKillUE가 다음 가비지 수집 주기 동안 메모리에서 할당을 해제하도록 표시됩니다. 또한 보류 중인 종료를 수동으로 확인하는 대신 더 FWeakObjectPtr<AActor>깔끔한 사용을 고려하세요.

EndPlay가 호출될 때 액터가 반드시 파괴될 필요는 없습니다. 예를 들어 s.ForceGCAfterLevelStreamedOut하위 false레벨이 빠르게 다시 로드되면 액터의 EndPlay가 호출되지만 액터는 "부활"될 수 있으며 재초기화되지 않은 로컬 변수와 함께 이전에 존재했던 액터와 정확히 동일한 액터가 됩니다. 기본값
  • AActor::OnDestroyed - Destroy에 대한 레거시 응답입니다. 레벨 전환 및 기타 게임 정리 기능에 의해 호출되므로 여기서 로직을 EndPlay로 옮기는 것이 좋습니다.


쓰레기 수거

객체가 파괴 대상으로 표시된 후 일정 시간이 지나면 가비지 수집은 해당 객체를 메모리에서 제거하고 사용 중이던 모든 리소스를 해제합니다.
객체가 소멸되는 동안 객체에 대해 다음 함수가 호출됩니다.

 

  1. UObject::BeginDestroy - 객체가 메모리를 확보하고 다른 멀티스레드 리소스(예: 그래픽 스레드 프록시 객체)를 처리할 수 있는 기회입니다. 파괴와 관련된 대부분의 게임플레이 기능은 EndPlay에서 더 일찍 처리되어야 합니다.
  2. UObject::IsReadyForFinishDestroy - 가비지 컬렉션 프로세스는 이 함수를 호출하여 객체를 영구적으로 할당 해제할 준비가 되었는지 여부를 결정합니다. false를 반환함으로써 이 함수는 다음 가비지 수집이 통과될 때까지 객체의 실제 소멸을 연기할 수 있습니다.
  3. UObject::FinishDestroy - 마지막으로, 객체가 실제로 파괴될 예정인데, 이는 내부 데이터 구조를 확보할 수 있는 또 다른 기회입니다. 이것은 메모리가 해제되기 전의 마지막 호출입니다.

고급 가비지 수집

언리얼 엔진 의 가비지 컬렉션 프로세스는 모두 함께 파괴되는 객체 클러스터를 구축합니다. 클러스터링은 개체를 개별적으로 삭제하는 것에 비해 가비지 수집과 관련된 총 시간과 전체 메모리 변동을 줄입니다. 개체가 로드되면 하위 개체가 생성될 수 있습니다. 개체와 해당 하위 개체를 가비지 수집기를 위한 단일 클러스터로 결합함으로써 엔진은 전체 개체가 해제될 준비가 될 때까지 클러스터에서 사용하는 리소스 해제를 지연한 다음 모든 리소스를 한 번에 해제할 수 있습니다.

대부분의 프로젝트에서는 가비지 수집을 구성하거나 수정할 필요가 전혀 없지만 가비지 수집기의 "클러스터링" 동작을 변경하여 다음과 같은 방법으로 효율성을 향상시킬 수 있는 몇 가지 특정한 경우가 있습니다.

  • 클러스터링 - 클러스터링을 끕니다. 프로젝트 설정 의 가비지 컬렉션 섹션 아래 가비지 컬렉터 UObject 클러스터 생성 옵션을 false로 설정할 수 있습니다. 대부분의 프로젝트에서 이로 인해 가비지 수집 효율성이 떨어지므로 성능 테스트에서 이점이 있는 것으로 밝혀진 경우 권장됩니다.

반응형