1. 보간(Interpolation)이란?
- 두 개의 값 사이에서 중간 값을 계산하여 자연스럽게 변화하도록 만드는 기술. 즉, 한 값에서 다른 값으로 부드럽게 이동하는 방법을 의미.
- 언리얼 엔진에서는 다양한 보간 함수가 제공되며, 그중 FMath::FInterpTo()와 FMath::RInterpTo()를 활용하면 캐릭터의 움직임과 회전을 자연스럽게 만들 수 있다.
언리얼 엔진의 주요 보간 함수
| FMath::Lerp() | 선형 보간 (일정한 비율로 변화) | 위치, 색상 변화 |
| FMath::FInterpTo() | 부드러운 값 변화 (속도 기반) | 속도, 감속 효과 |
| FMath::RInterpTo() | 부드러운 회전 변화 | 회전 보간 (기체 회전) |
| UKismetMathLibrary::Ease() | 다양한 이징 함수 제공 | 애니메이션 효과 |
2. FMath::FInterpTo()를 활용한 부드러운 이동 처리
float FMath::FInterpTo(float Current, float Target, float DeltaTime, float InterpSpeed);
- Current: 현재 값
- Target: 목표 값
- DeltaTime: 프레임당 경과 시간 (GetWorld()->GetDeltaSeconds() 활용)
- InterpSpeed: 변화 속도 (값이 클수록 빠르게 보간)
- 결과: Current 값이 Target 값으로 InterpSpeed 속도로 점진적으로 변경됨
2-1. ASpartaPawn에서 FMath::FInterpTo() 적용 예제
void ASpartaPawn::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
UpdateRotation(DeltaTime);
ApplyGravity(DeltaTime);
ApplyMovement(DeltaTime);
}
- Pawn 클래스의 Tick 함수 내부에는 CurrentVelocity(현재 속도) 벡터를 지속적으로 관리해주면서 그 값을 DeltaTime 만큼 곱하여 MoveDelta만큼 Pawn을 이동.
감속을 적용한 이동 처리 (ApplyMovement)
void ASpartaPawn::ApplyMovement(float DeltaTime)
{
if (!CurrentVelocity.IsNearlyZero(0.01f))
{
FVector MoveDelta = CurrentVelocity * DeltaTime; // Z 이동 포함
AddActorWorldOffset(MoveDelta, true);
CurrentVelocity.X = FMath::FInterpTo(CurrentVelocity.X, 0.0f, DeltaTime, DecelerationFactor);
CurrentVelocity.Y = FMath::FInterpTo(CurrentVelocity.Y, 0.0f, DeltaTime, DecelerationFactor);
}
}
- CurrentVelocity 값을 0.0f로 점진적으로 보간하여 자연스럽게 감속되는 효과를 구현.
플레이어 이동 (MoveForward, MoveRight)
void ASpartaPawn::MoveForward(float value, float Speed)
{
FVector ForwardVector = GetActorForwardVector();
FVector MoveDirection = ForwardVector * value * Speed;
CurrentVelocity.X = FMath::FInterpTo(CurrentVelocity.X, MoveDirection.X, GetWorld()->GetDeltaSeconds(), 2.0f);
CurrentVelocity.Y = FMath::FInterpTo(CurrentVelocity.Y, MoveDirection.Y, GetWorld()->GetDeltaSeconds(), 2.0f);
TargetRotation.Pitch = FMath::Clamp(value * -25.0f, -25.0f, 25.0f);
}
- Pawn이 이동할 때 CurrentVelocity가 목표 속도로 부드럽게 변화하도록 FInterpTo()를 사용.
중력 적용 (ApplyGravity)
void ASpartaPawn::ApplyGravity(float DeltaTime)
{
if (!IsOnFoot()) // 지면에 닿아 있지 않을 때 중력 적용
{
CurrentVelocity.Z += Gravity * DeltaTime; // 중력 적용
}
else if (CurrentVelocity.Z < 0) // 착지 시 아래로 떨어지는 중일 때만 속도 초기화
{
CurrentVelocity.Z = 0.0f;
}
}
상승/하강 (Ascend/Descend)
void ASpartaPawn::Ascend(const FInputActionValue& value)
{
if (!Controller) return;
CurrentVelocity.Z = FMath::FInterpTo(CurrentVelocity.Z, value.Get<float>() * CurrentSpeed, GetWorld()->GetDeltaSeconds(), 2.0f);
}
void ASpartaPawn::Descend(const FInputActionValue& value)
{
if (!Controller) return;
CurrentVelocity.Z = FMath::FInterpTo(CurrentVelocity.Z, -value.Get<float>() * CurrentSpeed, GetWorld()->GetDeltaSeconds(), 2.0f);
}
3. FMath::RInterpTo()를 활용한 부드러운 회전 처리
FRotator FMath::RInterpTo(FRotator Current, FRotator Target, float DeltaTime, float InterpSpeed);
- Current: 현재 회전 값
- Target: 목표 회전 값
- DeltaTime: 프레임당 경과 시간 (GetWorld()->GetDeltaSeconds() 활용)
- InterpSpeed: 변화 속도
- 결과: Current 값이 Target 값으로 InterpSpeed 속도로 점진적으로 변경됨
3-1. ASpartaPawn에서 FMath::RInterpTo() 적용 예제
회전 보간 적용 (UpdateRotation)
void ASpartaPawn::UpdateRotation(float DeltaTime)
{
if (IsOnFoot())
{
bIsFlying = false;
TargetRotation = FRotator(0.0f, GetActorRotation().Yaw, 0.0f);
}
else
{
bIsFlying = true;
TargetRotation.Pitch = FMath::FInterpTo(TargetRotation.Pitch, 0.0f, DeltaTime, 3.0f);
TargetRotation.Roll = FMath::FInterpTo(TargetRotation.Roll, 0.0f, DeltaTime, 3.0f);
}
SetActorRotation(FMath::RInterpTo(GetActorRotation(), TargetRotation, DeltaTime, 5.0f));
}
RInterpTo()를 사용하여 회전 값을 목표 회전 값으로 점진적으로 변화.
특히 Pitch와 Roll 값을 FInterpTo()로 부드럽게 보간하면서도,
전체적인 회전은 RInterpTo()로 처리하여 자연스럽게 회전하도록 구현.
4. 시연 영상
✏️오늘도 과제를 어찌저찌 마무리했습니다.
아직 실력이 부족하여 구현해보고자 했던 것에는 실패했지만 다음 주 공부와 연계하여 이루어낼 예정입니다.
'TIL > C++와 UE' 카테고리의 다른 글
| 파티클 시스템 (0) | 2025.02.11 |
|---|---|
| 게임 메뉴 UI 디자인 (0) | 2025.02.07 |
| 비행체 움직임 (0) | 2025.01.28 |
| 회전 관련 함수 및 Pawn 클래스 Look 함수 (1) | 2025.01.27 |
| 충돌 검사 (0) | 2025.01.24 |