[UE5] Timer

kkado·2024년 4월 5일
0

UE5

목록 보기
31/61
post-thumbnail

적 타워가 플레이어의 탱크를 향해 일정 시간마다 포탄을 발사하는 기능을 구현하려고 한다.
이를 위해 특정 콜백 함수를 일정 시간 후에 호출해 주는 타이머 기능을 알 필요가 있다.

타이머 관련 구조는 크게 세 가지로 구성되며 타이머매니저, 타이머핸들, 타이머가 그것이다.

구조 파악

타이머매니저는 전역적으로 모든 타이머 핸들러를 관리해준다.
글로벌 타이머 매니저는 Game Instance (게임 인스턴스) 오브젝트와 각 World (월드)에 존재한다. 타임 매니저와 함께 타이머를 셋업하는 데 사용되는 주 함수는 SetTimerSetTimerForNextTick 두 가지가 있다. 타이머매니저가 타이머핸들에 타이머를 추가할 수 있다. 타이머를 추가할 때는 콜백 함수와 타이머핸들의 이름, 주기 등을 설정한다.

멤버 변수 생성

FTimerHandle FireRateTimerHandle;
UPROPERTY(EditAnywhere, Category = "Combat")
float FireRate = 2;

void CheckFireCondition();

먼저 콜백 함수를 등록할 FTimerHandle 을 생성하고, 발사 주기(FireRate)를 만들었다. 발사 주기는 개발 과정에서 쉽게 수정할 수 있도록 하기 위해 EditAnywhere 프로퍼티를 설정했다.

그리고 주기마다 실행할 콜백 함수인 CheckFireCondition 을 만들었다. 이름에서도 알 수 있듯이 타워와 탱크까지의 거리를 확인하고 거리 안에 들어왔을 때 Fire 함수를 작동하도록 구성할 예정이다.


SetTimer

GetWorldTimerManager() 를 통해 현재 월드의 타이머매니저를 가져올 수 있다. (이후 타이머매니저의 멤버함수를 사용하기 위해서는 #include "TimerManager.h" 필요)

SetTimer는 여러 가지 형태로 오버로드되어 있다.

그 중에 이것을 사용하려고 한다.
인자로는 각각 사용할 타이머핸들, 콜백 함수를 호출할 객체명, 콜백 함수(의 주소값), 반복 주기, 반복 여부를 설정했다.

GetWorldTimerManager().SetTimer(FireRateTimerHandle, this, &ATower::CheckFireCondition, FireRate, true);

반복 여부가 true로 되어 있으면 일정 주기마다 게임이 종료될 때까지 계속 반복해서 콜백 함수를 호출하고, false로 되어 있으면 설정한 InRate 이후에 최초 1회만 호출한다.


콜백 함수 만들기

콜백 함수, 즉 일정 주기마다 수행할 작업은 다음과 같다.

  • 먼저 탱크가 타워의 사정거리 안에 들어와 있는지 계산
  • 사정거리 안에 들어와 있다면 발사 (Fire)

탱크와 타워의 거리를 계산하는 InFireRange 함수를 만들었다.

bool ATower::InFireRange()
{
    if (Tank != nullptr)
    {
        float Distance = FVector::Dist(GetActorLocation(), Tank->GetActorLocation());
        return (Distance <= FireDistance);
    }
    return false;
}

이를 CheckFireCondition 함수 안에 구현한다.

void ATower::CheckFireCondition()
{
    if (InFireRange())
    {
        Fire();
    }
}

결과

콜백 함수가 일정 주기마다 잘 실행되는지, 잘 실행된다면 Fire 함수까지 잘 실행되는지 판단하기 위해 Fire 함수에서 디버그 구체를 그려보도록 하고, 실행해서 결과를 살펴본다.

타워의 포신 부분이 잘 회전하고, 사정거리 안에 들어오니 2초 간격으로 구체를 생성, 즉 Fire 함수가 호출되고 있음을 알 수 있다.

profile
울면안돼 쫄면안돼 냉면됩니다

0개의 댓글