Quick Comparison
보간 함수를 먼저 고르지 말고, 언제 끝나야 하는지, 속도가 일정해야 하는지, 목표를 따라오는 감각이면 되는지를 정합니다. Lerp의 t는 거리나 속도가 아니라 0~1 진행도이고, SmoothDamp의 smoothTime은 근사적인 도달 감각입니다.
| 원하는 움직임 | Unity 선택 | 시간 값의 의미 |
|---|---|---|
| 0.5초 뒤 정확히 도착 | Lerp(start, end, elapsed / duration) | 진행도 t |
| 초당 3m로 이동 | MoveTowards(current, target, speed * deltaTime) | 이동 거리 |
| 카메라가 부드럽게 추적 | SmoothDamp | 감쇠 시간과 속도 상태 |
| 초당 일정한 각도로 회전 | Quaternion.RotateTowards | 각도 변화량 |
| 두 회전 사이의 duration 보간 | Quaternion.Slerp(start, end, t) | 진행도 t |
float elapsed;
Vector3 startPosition;
void Update()
{
elapsed += Time.deltaTime;
float t = Mathf.Clamp01(elapsed / 0.5f);
transform.position = Vector3.Lerp(startPosition, target.position, t);
}완료 시간과 일정 속도
Vector3.Lerp(a, b, t)는 t가 0이면 a, 1이면 b가 되는 보간입니다. 정해진 duration을 만들려면 출발점을 보관하고 elapsed time으로 t를 계산합니다. 매 frame current = Lerp(current, target, deltaTime * speed)처럼 현재값을 다시 a에 넣으면 목표에 가까워질수록 이동량이 줄어드는 지수적 수렴이 됩니다. 이는 follow 감각에는 쓸 수 있지만 정확한 도착 시간이나 일정 속도 이동은 아닙니다.
일정 속도가 요구되면 MoveTowards의 마지막 인수에 초당 속도와 deltaTime을 곱습니다. physics body를 움직이는 경우는 render frame의 Update가 아니라 Rigidbody의 물리 API와 FixedUpdate의 시간 계약을 따릅니다. 그래야 위치 보간 함수가 물리 충돌과 분리돼 보이는 일을 줄일 수 있습니다.
void Update()
{
transform.position = Vector3.MoveTowards(
transform.position,
target.position,
3f * Time.deltaTime);
}damping과 상태 변수
SmoothDamp는 목표를 향해 spring-damper처럼 부드럽게 움직이며 overshoot를 피하려고 시도합니다. smoothTime이 작을수록 더 빨리 따라오고, currentVelocity는 함수가 다음 frame을 위해 갱신하는 상태입니다. velocity를 local variable로 매번 새로 만들면 감쇠 상태가 사라지므로 field에 보관하고 ref로 넘깁니다.
Vector3 followVelocity;
void LateUpdate()
{
transform.position = Vector3.SmoothDamp(
transform.position, target.position,
ref followVelocity, 0.15f, 10f, Time.deltaTime);
}SmoothDamp의 smoothTime은 정확한 도착 deadline이 아니며, deltaTime이 0이면 velocity가 NaN이 될 수 있습니다. pause·custom time scale·수동 simulation에서 delta time을 넘길 때 이 경계를 확인합니다. 카메라 follow처럼 플레이 감각을 정하는 값은 한 수식의 정답보다 target 이동 속도와 frame rate를 포함한 playtest로 튜닝합니다.
회전 보간의 범위
Euler Z 각도처럼 한 축만 다룰 때는 LerpAngle, MoveTowardsAngle, SmoothDampAngle이 0/360도 경계를 처리합니다. 3D orientation 전체는 Quaternion API를 사용합니다. 정해진 duration의 부드러운 회전에는 Quaternion.Slerp(start, end, t), 일정한 각속도에는 Quaternion.RotateTowards(current, target, degreesPerSecond * deltaTime)가 읽기 쉽습니다.
Slerp와 Lerp 중 어느 쪽이 빠른가보다 결과 계약이 먼저입니다. 작은 회전에서 근사가 충분한지, camera·animation에서 일정한 회전 속도가 중요한지, 목표가 계속 바뀌는 follow인지 확인합니다. 어느 방식이든 현재 회전과 목표 회전을 매 frame 바꾸면 duration 기반 보간의 start/end 계약이 달라진다는 점을 분리해서 관리합니다.
Lerp(current, target, deltaTime * speed)는 만능 이동 공식이 아닙니다. 정해진 시간, 일정 속도, 부드러운 추적 중 하나를 먼저 고르고, physics movement와 render-frame 보간을 같은 위치 쓰기로 섞지 마세요.
참고 링크
2 sources