DeltaTime이 아닌 현재 시간을 사용하는 이유

김민수·2025년 1월 22일

언리얼 C++

목록 보기
21/32

1. DeltaTime과 현재 시간의 차이

  • DeltaTime: 프레임 간 시간 간격. 프레임마다 값이 달라지며, 프레임 속도(FPS)에 따라 값이 영향을 받는다.
    • 예) 60FPS일 때 DeltaTime ≈ 0.016초, 30FPS일 때 DeltaTime ≈ 0.033초
  • 현재 시간: 게임이 시작된 후 흐른 총 시간(초 단위).
    • 프레임 속도에 관계없이 절대적인 시간 값을 제공한다.


2. DeltaTime 기반 움직임의 한계

DeltaTime은 프레임 기반 움직임을 구현할 때 매우 유용하지만, 주기적인(반복적인) 움직임이나 절대 시간에 기반한 계산에는 부적합할 수 있다.

  1. 누적 오차 발생 가능성
    DeltaTime을 매 프레임마다 누적해서 움직임을 계산하면, 작은 오차가 쌓여 시간이 지남에 따라 움직임이 비정상적으로 보일 수 있다. 특히, 부동소수점 연산의 정밀도 한계로 인해 오차가 발생할 수 있다.
AccumulatedTime += DeltaTime; // DeltaTime을 누적
Position = FMath::Sin(AccumulatedTime); // 누적 시간을 기반으로 위치 계산

위 방식에서는 누적된 시간(AccumulatedTime)이 정확하지 않으면 부드러운 움직임이 깨질 수 있다.

  1. 프레임 속도에 따른 부드러움 차이
    DeltaTime을 누적하면 FPS가 낮거나 불안정할 때 움직임이 덜 부드러워질 가능성이 있다. 이 문제는 특히 고속 카메라 애니메이션이나 주기적인 진동을 구현할 때 눈에 띈다.

  2. 일관된 주기적 계산 필요
    주기적인 움직임(예: 사인파를 이용한 상하 움직임)에서, DeltaTime을 사용하면 시간이 지남에 따라 주기가 틀어지거나 계산의 부정확성이 누적될 수 있다. 이 경우 현재 시간을 사용하면 항상 정확한 주기적인 계산이 가능하다.



3. 현재 시간을 사용하는 이유

  1. 프레임 속도에 무관한 일관성
    현재 시간을 사용하면 프레임 속도가 높거나 낮아도 항상 정확한 계산이 가능하다. 이는 FPS가 변동되더라도 움직임이 자연스럽고 일관되게 유지되도록 한다.

  2. 정확한 주기 계산
    사인파 같은 주기적인 계산에서 누적된 오차를 방지하고, 항상 정확한 결과를 반환한다.

float Time = GetWorld()->GetTimeSeconds(); // 절대 시간
float ZPosition = Amplitude * FMath::Sin(Frequency * Time);

위 코드는 항상 Time을 기준으로 계산하기 때문에, FPS가 변해도 사인파의 주기가 유지된다.

  1. 재현 가능한 결과
    현재 시간을 사용하면 특정 시점에서 동일한 입력 값이 항상 동일한 결과를 반환한다. 이 특징은 테스트나 디버깅 시에도 유용하다.


4. 현재 시간을 사용하는 방법

언리얼 엔진에서는 GetWorld()->GetTimeSeconds()를 사용하여 게임 시작 후 흐른 총 시간을 가져올 수 있다. 이를 활용하면 DeltaTime 누적 없이 절대적인 시간 값을 기반으로 계산할 수 있다.

사인파를 이용한 상하 이동

void AMyActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    float Time = GetWorld()->GetTimeSeconds(); // 현재 시간
    float Amplitude = 50.0f;                  // 진폭
    float Frequency = 1.0f;                   // 주파수

    FVector NewLocation = StartLocation;
    NewLocation.Z += Amplitude * FMath::Sin(Frequency * Time); // 현재 시간 기반 계산
    SetActorLocation(NewLocation);
}
  • FMath::Sin(Frequency * Time)는 현재 시간을 기준으로 위치를 계산한다.
  • DeltaTime을 사용하지 않아도 프레임 속도와 관계없이 일관된 상하 움직임을 유지한다.

색상 변화

void AMyActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    float Time = GetWorld()->GetTimeSeconds();
    float Brightness = (FMath::Sin(Time) + 1.0f) / 2.0f; // -1 ~ 1을 0 ~ 1로 변환

    FLinearColor NewColor = FLinearColor::LerpUsingHSV(FLinearColor::Red, FLinearColor::Blue, Brightness);
    MyMaterialInstance->SetVectorParameterValue("BaseColor", NewColor);
}
  • 현재 시간을 기준으로 FMath::Sin(Time)을 사용해 색상이 부드럽게 변하도록 만든다.
  • FPS와 무관하게 색상이 일정한 속도로 변한다.

5. 사용 시기

DeltaTime을 사용해야 하는 경우

  • 속도 기반 계산:
    DeltaTime은 속도 = 거리 / 시간 공식을 구현할 때 적합하다. 오브젝트가 프레임마다 일정한 거리만큼 이동하도록 할 때 사용된다.
FVector NewLocation = CurrentLocation + Velocity * DeltaTime;
  • 물리 연산:
    DeltaTime은 물리 연산(예: 중력, 가속도)에 필수적이다.

현재 시간을 사용해야 하는 경우

  • 주기적인 움직임:
    사인파, 진동, 물결 등 주기적인 효과는 현재 시간 기반으로 계산하는 것이 정확하다.

  • FPS 독립적인 계산:
    DeltaTime 누적으로 인해 발생하는 오차를 방지해야 할 때 사용한다.

  • 절대 시간 기준의 연산:
    특정 시간 기반의 이벤트(예: 색상 변화, 애니메이션 동기화)가 필요할 때 사용한다.

profile
안녕하세요

0개의 댓글