내일배움캠프/Unity Final Projcet
[Unity] 타워디펜스 게임에서 2배속 기능과 실시간 타이머 유지 구현
danpat77
2025. 5. 1. 20:32
타워디펜스 게임을 만들다 보면
적 유닛의 움직임이나 웨이브 진행 속도를 빠르게 하고 싶은 경우가 많습니다.
이럴 때 Time.timeScale을 활용한 배속 기능이 유용하지만,
실시간으로 흐르는 플레이 타이머까지 함께 빨라져 버리는 문제가 발생합니다.
구현 목표
- 버튼 클릭으로 게임 배속을 1배속 ↔ 2배속으로 전환
- 배속 여부와 무관하게 **UI 타이머(GamePlayTimer)**는 실제 시간 기준으로 작동
- 타이머는 게임 진행 시간(분:초)을 표시
배속 버튼 구현
[SerializeField] private Button speedButton;
[SerializeField] private TextMeshProUGUI speedText;
private bool isFast = false;
private void Start()
{
speedButton.onClick.AddListener(OnClickGameSpeedButton);
}
private void OnClickGameSpeedButton()
{
isFast = !isFast;
Time.timeScale = isFast ? 2f : 1f;
speedText.text = isFast ? "x2" : "x1";
}
- Time.timeScale을 통해 게임의 전체 시간 속도를 조절합니다.
- TextMeshProUGUI로 현재 배속 상태를 사용자에게 표시합니다.
실시간 타이머 유지 (unscaledDeltaTime 사용)
private Coroutine timerCoroutine;
public void StartTimer()
{
timerCoroutine = StartCoroutine(GamePlayTimer());
}
public void StopTimer()
{
if (timerCoroutine != null)
{
StopCoroutine(timerCoroutine);
timerCoroutine = null;
}
}
IEnumerator GamePlayTimer()
{
float timer = 0f;
while (BattleManager.Instance.CurrentBattle.isBattle)
{
timer += Time.unscaledDeltaTime; // 실제 시간 기준으로 증가
playTime.text = SetTimeText(timer);
yield return null;
}
playTime.text = SetTimeText(timer);
}
public string SetTimeText(float time)
{
int minutes = (int)(time / 60);
int seconds = (int)(time % 60);
return string.Format("{0:00}:{1:00}", minutes, seconds);
}
- Time.unscaledDeltaTime은 Time.timeScale 영향을 받지 않으므로, 실제 시간 흐름을 그대로 측정합니다.
- deltaTime을 사용하면 2배속 시 1초에 2초가 증가하는 문제가 발생하지만, unscaledDeltaTime을 사용하면 정확한 시간 측정이 가능하여 정확하게 게임 플레이 시간을 측정이 가능합니다.
마무리
- Time.timeScale은 전체 게임의 시간 흐름을 조절하지만, 특정 시스템(UI 타이머 등)은 실시간 기준으로 유지해야 하는 경우가 있습니다.
- 이럴 때는 Time.unscaledDeltaTime을 활용하면 깔끔하게 해결할 수 있습니다.
- 또한 AudioSource.pitch 등 추가 요소에 대해 배속 적용 여부를 개별적으로 처리할 수도 있습니다.