KoreanFoodie's Study

유니티에서 일시정지 및 특정 물체 시간 정지 구현하기 본문

Game Dev/Unity : Study

유니티에서 일시정지 및 특정 물체 시간 정지 구현하기

GoldGiver 2022. 7. 9. 23:17
Udemy 관련 개념 정리 및 Dev Log 를 기록하고 있습니다!

유니티에서 일시정지하기

유니티에서는 일시 정지 기능을 어떻게 구현하면 될까?
먼저 결론만 말하자면, Time.timeScale 값을 조절하여 Time.deltaTime 을 0 으로 만드는 방식을 이용하면 된다.

void PauseGame ()
    {
        Time.timeScale = 0;
    }
void ResumeGame ()
    {
        Time.timeScale = 1;
    }

이런 방식을 이용하면, 각 게임 오브젝트들의 Update 내 함수에서 Time.deltaTime 에 의존하는 모든 동작이 멈추게 된다.
이 말은즉슨, Time.deltaTime 에 의존하지 않는 녀석들의 경우에는 여전히 일시정지라는 본연의 목적과 다른 동작을 할 수 있음을 의미한다.
따라서 해당 부분들만 추가적으로 고려해 주면 된다. 예시를 들어보기 전에, 해당 포스트는 이 환상적인 칼럼을 바탕으로 쓰였음을 밝힌다. 정말 아름다운 글이니 시간이 남으면 직접 읽어봐도 좋을 것 같다!

멈추는 것과 멈추지 않는 것

Time.timeScale 을 0 으로 설정해도 Update 함수는 여전히 호출된다. (단, FixedUpdate 는 아예 호출되지 않는다)
그럼 만약 우리가 특정 물체의 경우에만 일시정지를 시키고 싶거나, 그 반대의 경우를 구현하고 싶으면 어떻게 해야 할까? (예를 들어 캐릭터만 움직일 수 있다던지)

이 경우, Time.deltaTime 대신 Time.unscaledDeltaTime 을 사용하면 된다!

  • Time.deltaTime 대신 Time.unscaledDeltaTime 사용
  • Time.fixedDeltaTime 대신 Time.fixedUnscaledDeltaTime 사용
  • Time.time 대신 Time.unscaledTime 사용

추가적으로, 시간을 멈춘다고 해서 코루틴이 정지하는 것은 아니다. 코루틴의 경우 일시정지를 하지 않도록 만들고 싶다면, 위의 경우처럼 Time.unscaledDeltaTime 등을 사용하면 된다.
혹은 WaitForSeconds 함수 대신 WaitForSecondsRealTime 을 사용해 스케일에 상관없이 실제 시간에 기반한 동작을 구현할 수도 있다.

UI 등 오브젝트 애니메이션 재생하기

일반적으로 게임을 일시정지하면 일시정지 UI 애니메이션이 재생된다.
위의 동작을 원한다면, Animator 인스펙터로 이동해 Update Mode 설정을 Unscaled Time 으로 바꿔주면 된다!


주의 : 플레이어 인풋 비활성화하기

예를 들어, 클릭을 하면 플레이어의 방향이 전환되는 기능을 구현했다고 하자(Time.deltaTime 과 상관없이). 만약 일시정지 상태에서 계속 클릭을 하면, 플레이어의 방향이 전환되어 스프라이트가 망가지거나 이상해질 수도 있다. 이를 위해, GamePause 함수를 정의할 때 플레이어 인풋을 처리할 것인지를 추가로 정의해주면 좋다.

void Update()
{
    if (!PauseControl.gameIsPaused)
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // Make the player jump!
        }
    }
    else
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // Player can't jump! (The game is paused)
        }
    }
}

PauseControl 에 정의된, gameIsPaused 값을 체크해 게임이 일시정지 상태가 아닐 때에만 인풋을 처리하도록 만들었다.

마지막 : 음악 일시정지하기

음악의 경우 다음과 같이 처리해주면 간단하다.

void PauseGame ()
    {
        Time.timeScale = 0f;
        AudioListener.pause = true;
    }
void ResumeGame ()
    {
        Time.timeScale = 1;
        AudioListener.pause = false;
    }

음악재생의 경우 Play Scheduled 를 통해 음악이 재생되게 되는데, 참조하는 값이 Audio DSP time value 이다. AudioListener 를 일시정지하면 DSP time value 도 일시정지된다!

마무리

시간 정지에는 다양한 방법이 있지만, Time.timeScale 을 0 으로 주고 추가적인 부분을 일시정지 상태에 맞게 고치는 것이 효율적이다.
또한 TimeScale 을 응용하면 플레이어만 자유롭고 빠르게 움직일 수 있다던지 하는 기능을 추가해볼 수도 있을 것이다.

Comments