본문 바로가기
🌐 유니티 (Unity)

Day 68 - 유니티에서 시간을 멈춰도 코루틴이 작동하게 하는 방법 🎮

by shin0707 2025. 1. 22.
728x90
반응형

유니티에서 시간을 멈춰도 코루틴이 작동하게 하는 방법

  • 주제

>>  기본 문제: Time.timeScale = 0;

>>  코루틴에 Real-Time 적용하기

>>  Real-Time을 사용하는 이유

>>  실전 예제: 정지 화면에서 카운트다운 구현

>>  최적화 팁


  • 공부내용

Unity에서 설정 창을 열거나 정지 버튼을 눌렀을 때, 

게임 진행을 멈추기 위해 Time.timeScale = 0;을 사용하는 경우가 많다. 

하지만 timeScale이 0으로 설정되면 코루틴도 멈추게 되어 

이펙트나 실시간으로 업데이트되던 요소가 함께 멈추는 문제가 발생한다. 

이번 게시글에서는 이러한 상황에서도 코루틴을 작동하게 유지하는 방법을 알아본다.

 

1. 기본 문제: Time.timeScale = 0;

Unity에서 시간의 흐름을 제어하는 Time.timeScale은 게임 속 모든 시간 관련 동작을 조정한다. 

하지만 이는 단순히 게임의 움직임뿐 아니라 코루틴, 애니메이션, 물리 계산 등에도 영향을 미친다.

 

1-1. 문제 상황

- 게임이 정지되었을 때, UI 애니메이션 또는 카운트다운 타이머와 같은 기능도 멈춤.
- 코루틴 기반의 이펙트(예: 점멸 효과) 또는 실시간 이벤트 처리가 중단됨.

 


2. 코루틴에 Real-Time 적용하기

Unity에서 시간을 멈추더라도 코루틴을 계속 실행하려면, 

Real-Time(실제 시간)을 기준으로 코루틴을 설정하면 된다. 

이를 위해 Time.unscaledDeltaTime과 WaitForSecondsRealtime을 활용할 수 있다.

 

 

2-1. WaitForSecondsRealtime 사용법

WaitForSecondsRealtime은 timeScale의 영향을 받지 않는 코루틴 대기 메서드이다. 

아래는 사용 예제이다:

using UnityEngine;

public class PauseEffect : MonoBehaviour
{
    public GameObject effectObject;

    private void Start()
    {
        StartCoroutine(BlinkEffect());
    }

    private IEnumerator BlinkEffect()
    {
        while (true)
        {
            effectObject.SetActive(!effectObject.activeSelf);
            yield return new WaitForSecondsRealtime(0.5f); // Real-Time 기준 0.5초 대기
        }
    }
}

위 코드는 게임의 timeScale 값이 0이더라도, 이펙트가 계속 깜빡이는 효과를 유지한다.

 


3. Real-Time의 장점과 단점

3-1. 장점

- UI 애니메이션이나 이펙트가 정지 상태에서도 정상적으로 동작.

- timeScale 변경과 무관하게 정확한 시간을 기반으로 동작.

 

3-2. 단점

- Real-Time을 과도하게 사용하면 물리 계산과 게임의 시간 흐름 간 불일치가 발생할 수 있음.

 


4. 실전 예제: 정지 화면에서 카운트다운 구현

4-1. 시나리오

플레이어가 게임을 정지했을 때, UI 상에서 3초 카운트다운을 표시한 후 게임을 재개하는 기능을 구현한다.

 

4-2. 코드 예제

using UnityEngine;
using UnityEngine.UI;

public class PauseManager : MonoBehaviour
{
    public Text countdownText;

    public void PauseGame()
    {
        Time.timeScale = 0;
        StartCoroutine(CountdownResume());
    }

    private IEnumerator CountdownResume()
    {
        for (int i = 3; i > 0; i--)
        {
            countdownText.text = i.ToString();
            yield return new WaitForSecondsRealtime(1f); // Real-Time 기준 1초 대기
        }

        Time.timeScale = 1;
        countdownText.text = "";
    }
}

위 코드는 timeScale이 0으로 설정된 상태에서도 카운트다운 텍스트를 정상적으로 업데이트한다.

 


5. 최적화 팁

- Real-Time 사용 최소화

Real-Time 코루틴은 게임의 물리 연산과 무관하게 동작하기 때문에 주요 게임 로직과 분리하여 사용한다.

 

- UI와 비게임 로직에 활용

Real-Time 코루틴은 주로 UI 애니메이션, 효과, 카운트다운 등에 사용한다.

 

- 테스트 환경에서 점검

다양한 timeScale 설정에서 코루틴이 의도대로 동작하는지 확인한다.


<결론>

 

Time.timeScale을 사용하여 게임을 멈추는 것은 매우 유용하지만, 동시에 코루틴이 멈추는 부작용이 발생할 수 있다. 이를 해결하기 위해 WaitForSecondsRealtime 또는 Time.unscaledDeltaTime을 활용하면 게임의 흐름과 무관하게 실시간 처리를 구현할 수 있다. 적절히 활용하여 정지 상태에서도 생동감 있는 게임을 만들어보자!

728x90

 

728x90
반응형

loading