생성자 Constructor
, PostInitializeComponents
, BeginPlay
등이 각각 언제 호출되는지 알아야 적절한 곳에 초기화 코드를 배치할 수 있음.CreateDefaultSubobject
은 생성자에서,BeginPlay
에서 처리하는 등Tick
함수는 비용이 클 수 있음.Tick
을 활성화하거나 이벤트 기반으로 전환해 최적화해야 함.Destroyed
, EndPlay
등) 메모리를 해제하거나 특정 상태를 저장해야 할 수 있음.언리얼 엔진의 Actor 동작 순서
1. 생성 -> 2. 초기화 -> 3. 월드 배치 -> 4. Tick(실행) -> 5. 제거 순으로 동작
// 헤더
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Item.generated.h"
DECLARE_LOG_CATEGORY_EXTERN(LogItem, Display, All);
UCLASS()
class STUDY_API AItem : public AActor
{
GENERATED_BODY()
public:
AItem(); // 생성자. 초기화 계열.
protected:
// 초기화 계열
virtual void PostInitializeComponents() override;
virtual void BeginPlay() override;
// 실행 계열
virtual void Tick(float DeltaTime) override;
// 소멸 계열
virtual void Destroyed() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
};
// cpp 파일
#include "Item.h"
DEFINE_LOG_CATEGORY(LogItem);
AItem::AItem()
{
// Tick을 활성화해, 매 프레임 Tick 함수가 호출되도록 설정
PrimaryActorTick.bCanEverTick = true;
}
void AItem::PostInitializeComponents()
{
Super::PostInitializeComponents();
UE_LOG(LogItem, Warning, TEXT("%s PostInitializeComponents"), *GetName());
}
void AItem::BeginPlay()
{
Super::BeginPlay(); // 반드시 부모의 함수도 호출해줄 것.
UE_LOG(LogItem, Warning, TEXT("%s BeginPlay"), *GetName());
}
void AItem::Tick(float DeltaTime)
{
Super::Tick(DeltaTime); // 반드시 부모의 함수도 호출해줄 것.
}
// 소멸 이벤트 함수들은 부모 함수 호출 전에 로그를 찍도록 함
// 상위 함수 호출과 함께 사라지는 것을 방지하기 위함.
void AItem::Destroyed()
{
UE_LOG(LogItem, Warning, TEXT("%s Destroyed"), *GetName());
Super::Destroyed();
}
void AItem::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
UE_LOG(LogItem, Warning, TEXT("%s EndPlay"), *GetName());
Super::EndPlay(EndPlayReason);
}
AItem();
CreateDefaultSubobject
등으로 컴포넌트 생성 및 변수 초기화를 수행virtual void PostInitializeComponents() override;
virtual void BeginPlay() override;
SpawnActor
등으로 새 액터가 생성될 때 한 번 호출.BeginPlay
에서 초기화.virtual void Tick(float DeltaTime) override;
PrimaryActorTick.bCanEverTick = true;
설정 필요.Tick
을 쓰지 않는 것이 성능에 유리.virtual void Destroyed() override;
Destroy()
함수를 직접 호출하여 액터를 제거할 때 직전에 호출됩니다.Destroyed()
가 불린 뒤에는 최종적으로 EndPlay()
도 함께 호출됩니다.new
또는 동적 할당한 오브젝트가 있다면 여기서 delete
하거나 해제합니다.virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
EEndPlayReason::Type
: 어떤 이유로 EndPlay가 호출됐는지 구분.Destroyed()
는 건너뛸 수 있음.EndPlay()
에서 수행하는 것이 안전.GetWorldTimerManager().ClearTimer(…)
와 같이 타이머를 정리합니다.