오늘 한일
- c++ 언리얼엔진 강의 노션 보고 따라치기
- 지뢰폭발 지연 로직 만들기
타이머 시스템 (FTimerManager)
학습 개요
언리얼 엔진에서 “특정 시간(초)이 지난 후에 함수를 지연 실행”하거나 “주기적으로 반복 호출”해야 할 때 사용하는 타이머 매니저(FTimerManager)의 작동 원리와 사용법을 학습했습니다.
학습 코드 : 지뢰 폭발 지연 로직
클래스 내부에 정의된 멤버 함수 주소(&클래스명::함수명)를 넘겨 실행하는 방식
ExplosionDelay(5초) 후에 지뢰의Explode함수를 실행합니다. (단발성)
void AMineItem::ActivateItem(AActor* Activator)
{
if (bHasExploded) return;
Super::ActivateItem(Activator);
// 타이머 매니저를 통해 Explode 함수를 ExplosionDelay초 후에 실행하도록 예약
GetWorld()->GetTimerManager().SetTimer(
ExplosionTimerHandle, // 1. 타이머를 제어할 핸들 (영수증)
this, // 2. 함수를 실행할 주체 (객체)
&AMineItem::Explode, // 3. 실행할 함수의 메모리 주소
ExplosionDelay, // 4. 대기 시간 (초 단위)
false // 5. 반복 여부 (false = 단발성)
);
bHasExploded = true;
}핵심 개념 및 매개변수 정리
1. GetWorld()->GetTimerManager()
- 월드 전체의 시간 흐름을 관리하는 매니저를 가져오는 함수입니다.
- 언리얼 엔진에서는 틱(Tick)마다 매니저가 예약된 타이머들을 감시하며, 지정한 대기 시간이 지나면 등록된 함수를 자동으로 깨워 실행해 줍니다.
2. SetTimer 함수의 5대 매개변수
FTimerHandle(타이머 핸들)- 개념: 실행할 타이머를 가리키는 **고유 식별자(영수증)**입니다.
- 용도: 이 식별자를 보관해 두고 있어야, 나중에 타이머가 끝나기 전에 취소(
ClearTimer)하거나 일시 정지할 수 있습니다.
this(객체 주소)- 개념: 호출할 멤버 함수가 어떤 객체(인스턴스) 내부에서 실행될지 지정합니다. 여기서는 지뢰 자기 자신(
this)이 실행 주체가 됩니다.
- 개념: 호출할 멤버 함수가 어떤 객체(인스턴스) 내부에서 실행될지 지정합니다. 여기서는 지뢰 자기 자신(
&AMineItem::Explode(실행할 함수 주소)- 개념: 딜레이가 만료되었을 때 실제로 호출할 함수의 메모리 주소를 가리킵니다.
- 제약: 이 방식으로 묶을 함수는 매개변수가 없고, 반환 타입이
void인 함수여야 합니다.
ExplosionDelay(대기 시간)- 개념: 몇 초 후에 함수를 실행할지 지정하는
float타입의 시간 단위 값입니다.
- 개념: 몇 초 후에 함수를 실행할지 지정하는
bLoop(반복 여부)- 개념:
true이면 지정한 시간이 지날 때마다 함수를 무한 반복해서 호출하고,false이면 딱 한 번만 실행하고 타이머가 종료됩니다. - 예시: 지뢰 폭발은 한 번만 일어나야 하므로
false를 지정합니다.
- 개념:
추가 기능
1. 타이머 예약 및 실행 (SetTimer)
시간 지연 후 특정 함수를 실행하게 설정하는 핵심 기능
① 클래스 멤버 함수 호출 방식 (지뢰 폭발 & 스테이지 시간 초과)
위에 올린 클래스 내부에 정의된 멤버 함수 주소(&클래스명::함수명)를 넘겨 실행하는 방식
-실제 코드 예시(스테이지 시간 초과):
LevelDuration(30초) 후에 게임이 끝나도록OnLevelTimeUp함수를 실행합니다. (단발성)
// SpartaGameState.cpp 내부
GetWorldTimerManager().SetTimer(
LevelTimerHandle,
this,
&ASpartaGameState::OnLevelTimeUp,
LevelDuration,
false
);실제 코드 예시 3 (HUD 실시간 반복 갱신):
- 화면의 UI를 계속 업데이트하기 위해 0.1초마다 반복적으로
UpdateHUD함수를 실행합니다. (반복성)
// SpartaGameState.cpp 내부
GetWorldTimerManager().SetTimer(
HUDUpdateTimerHandle,
this,
&ASpartaGameState::UpdateHUD,
0.1f, // 대기 시간: 0.1초
true // 반복 여부: true (무한 반복)
);② 람다식(Lambda)을 활용한 즉석 실행 방식 (이펙트 자동 파괴)
따라서 별도의 클래스 함수를 정의하지 않고, 일회성으로 사용할 짧은 로직을 현장에서 즉시 함수 형태로 조립해 실행하는 방식입니다.
- 실제 코드 예시 (아이템 획득 이펙트 수명 제어):
- 이펙트가 스폰되고 2초 뒤에 이펙트 컴포넌트를 파괴(
DestroyComponent)하는 코드가 람다식([Particle](){ ... })으로 즉석 전달되었습니다.
- 이펙트가 스폰되고 2초 뒤에 이펙트 컴포넌트를 파괴(
// BaseItem.cpp 내부
GetWorld()->GetTimerManager().SetTimer(
DestroyParticleTimerHandle,
[Particle]() // 람다 함수 시작 (사용할 변수를 캡처)
{
Particle->DestroyComponent(); // 2초 뒤 이 코드 실행
},
2.0f, // 2초 대기
false
);2. 타이머 남은 시간 구하기 (GetTimerRemaining)
실행 중인 타이머가 만료되기까지 시간이 얼마나 남았는지 확인하는 함수입니다.
- 실제 코드 예시 (남은 시간 UI 출력):
- 게임 화면(HUD)에 남은 제한 시간을 소수점 첫째 자리까지 표시하기 위해 사용 중입니다.
// SpartaGameState.cpp 내부
// LevelTimerHandle 타이머의 남은 시간(float)을 구함
float RemainingTime = GetWorldTimerManager().GetTimerRemaining(LevelTimerHandle);
// 구한 남은 시간을 가공하여 UI 텍스트 컴포넌트(TimeText)에 설정
TimeText->SetText(FText::FromString(FString::Printf(TEXT("Time: %.1f"), RemainingTime)));3. 작동 중인 타이머 강제 해제/취소 (ClearTimer)
예약되어 대기 중인 타이머가 작동하지 못하게 중도 취소하는 함수입니다.
- 실제 코드 예시 (스테이지 클리어 시 시간 초과 방지):
- 코인을 다 먹어서 레벨을 클리어(
EndLevel)했을 때, 백그라운드에서 돌아가던 30초 스테이지 제한 시간 타이머를 취소합니다. (만약 취소하지 않으면, 다음 레벨로 넘어간 후에도 30초 타이머가 울려 억울하게 게임 오버가 됩니다).
- 코인을 다 먹어서 레벨을 클리어(
-
// SpartaGameState.cpp 내부
// 레벨이 끝났으므로 30초 타임아웃 타이머(LevelTimerHandle)를 즉시 제거 GetWorldTimerManager().ClearTimer(LevelTimerHandle);
#### 4.기타
- **타이머 취소 (`ClearTimer`)**
- 폭발하기 전에 지뢰를 해제하는 기능 등을 구현할 때 사용합니다.
- `GetWorld()->GetTimerManager().ClearTimer(ExplosionTimerHandle);`
- **남은 시간 확인 (`GetTimerRemaining`)**
- 지뢰 폭발까지 몇 초 남았는지 실시간으로 계산해 화면 UI에 표시할 때 매우 유용합니다.
- `float Remaining = GetWorld()->GetTimerManager().GetTimerRemaining(ExplosionTimerHandle);`
- **일시 정지 및 재개 (`PauseTimer` / `UnPauseTimer`)**
- 게임이 일시 정지되거나 메뉴 창이 켜졌을 때 폭발 타이머를 잠깐 멈추는 용도로 활용합니다.
---
[[TIL]]
[[NBC]]