Quick Reference
| 값 | 시간 축 | 호출 위치 | 사용할 일 |
|---|---|---|---|
Time.deltaTime | scaled, 이전 렌더 프레임부터의 간격 | Update, LateUpdate | Transform 이동, gameplay 타이머 |
Time.fixedDeltaTime | scaled, 물리 step 하나의 game time | FixedUpdate | Rigidbody 이동·물리 계산 |
Time.unscaledDeltaTime | 실제 시간, timeScale 무시 | Update 등 | pause UI, realtime 카운트다운 |
Time.smoothDeltaTime | 최근 frame delta의 평활값 | 시각 보간 | 화면 흔들림 완화용 보조 값 |
deltaTime을 곱하면 speed를 "프레임당"이 아닌 "초당" 단위로 쓸 수 있습니다. 단, FixedUpdate 안의 Time.deltaTime은 fixedDeltaTime을 반환하므로, 물리 코드에서는 의도를 드러내기 위해 fixedDeltaTime을 직접 쓰는 편이 좋습니다.
private void Update()
{
transform.position += Vector3.forward * speed * Time.deltaTime;
}
private void FixedUpdate()
{
_rb.MovePosition(_rb.position + direction * speed * Time.fixedDeltaTime);
}프레임 시간의 경계
긴 프레임은 그대로 한 번에 이동하지 않을 수 있습니다
deltaTime은 scaled 시간이며 Time.maximumDeltaTime으로 상한이 정해집니다. 앱이 백그라운드에 있었거나 동기 로딩으로 프레임이 길어지면 실제 경과 시간과 deltaTime이 같지 않을 수 있습니다. 이 상한은 한 프레임에 캐릭터가 멀리 튀는 것을 완화하지만, elapsed time을 정확히 기록하는 wall-clock 용도에는 맞지 않습니다.
게임플레이 쿨다운처럼 프레임 단위 진행이 목적이면 deltaTime 누적이 자연스럽습니다. 로그인 만료, 서버 timeout, pause 중 카운트다운처럼 실제 시간 기준이어야 하면 unscaledTime 또는 서비스가 제공하는 clock을 선택합니다.
private float _cooldownRemaining;
private void Update()
{
_cooldownRemaining = Mathf.Max(0f, _cooldownRemaining - Time.deltaTime);
if (Input.GetKeyDown(KeyCode.Space) && _cooldownRemaining == 0f)
{
Fire();
_cooldownRemaining = cooldownSeconds;
}
}첫 Update, domain/scene reload 직후, timeScale 변경 직후에는 deltaTime이 작거나 예상 밖일 수 있습니다. 첫 프레임을 임의로 버리는 대신, 보간 시작 위치·타이머 초기값을 Awake/OnEnable에서 명시하고 해당 전환을 재현해 확인합니다. OnGUI와 layout/repaint처럼 한 프레임에 여러 번 호출될 수 있는 callback에서는 deltaTime 누적을 하지 않습니다.
smoothDeltaTime은 시뮬레이션 값이 아닙니다
smoothDeltaTime은 최근 frame delta를 평균 내 일시적인 변화가 화면에 덜 드러나게 하는 값입니다. 카메라와 UI 보간을 보기 좋게 만들 수 있지만, 물리·쿨다운·네트워크와 같이 실제 게임 진행을 결정하는 값으로 바꾸면 반응이 의도적으로 늦어질 수 있습니다.
private void LateUpdate()
{
float t = 1f - Mathf.Exp(-followSharpness * Time.smoothDeltaTime);
transform.position = Vector3.Lerp(transform.position, target.position, t);
}자주 틀리는 부분
| 증상 | 원인 | 선택 |
|---|---|---|
| 고사양 기기에서 더 빨리 이동 | 프레임당 거리만 더했습니다. | speed * Time.deltaTime으로 초당 단위를 만듭니다. |
| pause UI 타이머가 멈춤 | scaled deltaTime을 썼습니다. | unscaledDeltaTime을 씁니다. |
| 긴 프레임 뒤 타이머와 실제 시간이 다름 | maximumDeltaTime 상한과 frame boundary가 있습니다. | 게임 시간인지 wall-clock인지 다시 고릅니다. |
| 물리 이동이 흔들림 | Update 시간과 Rigidbody 변경을 섞었습니다. | FixedUpdate와 fixedDeltaTime으로 모읍니다. |
| 카메라가 미세하게 튐 | 물리 step과 렌더 frame의 차이가 보입니다. | interpolation, LateUpdate, 필요할 때 smoothDeltaTime을 함께 점검합니다. |
deltaTime은 정확한 stopwatch가 아닙니다. 프레임 기반 gameplay를 안정시키기 위한 시간값입니다. 값이 클 때 코드를 임의로 clamp하면 순간 이동은 숨길 수 있지만, 그만큼 진행 시간을 잃습니다. clamp가 필요한 시스템이라면 그 손실이 게임 규칙상 허용되는지 먼저 정합니다.
참고 링크
4 sources