유니티 프로그램

[유니티] UNITY 시간이 느리게 흐르게 하거나 멈추게 하려면 어떻게 할까요?

비도르 2022. 9. 26. 17:05

[유니티] UNITY 시간이 느리게 흐르게 하거나 멈추게 하려면 어떻게 할까요?

 

안녕하세요. 오늘도 약간씩 비를 흩뿌리는 흐리도록 평화로운 9월의 마지막주입니다.

이전에 타이머를 만드는 것에 대해서 다뤄봤었는데요. 이번에는 시간을 느리게 흐르도록 하는 방법에 대해서 알아보겠습니다. 현실에서도 이렇게 시간을 멈추거나 느리게 흐르게 할 수있었으면 좋겠네요. ^^

 

시간을 흐르게 할 때 주로 Time.deltaTime 속성을 사용하게 됩니다. 그 기능상 1초에 10프레임을 나타냄으로 인해서, 다양한 성능을 가지는 모바일에서 동일하게 시간을 흐르게 할 수있기 때문입니다.

이때, Time.timeScale 속성값을 조정하면 간단히 시간의 흐름을 변경할 수 있습니다.

 

Time.timeScale = 1.0f (정상적인 시간 흐름)

;값이 작아지면 느려짐

 

그럼, How??? 어떻게 Time.timeScale을 사용하는지 알아보겠습니다.

 

아래의 순서로 설명을 하겠습니다.

1. Time.timeScale 값을 변경하기

2. Time.unscaledDeltaTime 을 적용해보기


자세한 방법은 아래의 예제를 통해서 얘기하겠습니다.


[예제] 시간을 느리게해서 큐브 회전속도를 조정하기

먼저, 아래와 같이 화면을 구성하였습니다. Cube를 2개 추가해서 왼쪽에는 ' TestCube ' 라는 이름으로 생성하고 오른쪽에는 ' TestCube2 ' 라는 이름으로 생성했습니다. 그리고 , 그 위에 시간을 표현할 수있도록 ' Text '를 생성해서 각각 놓아두었습니다. 이때 이름은 각각 ' Time1 ' , ' Time2 '  라고 했고 구분이 될 수있도록 오른쪽은 글자색을 약간 붉게 하였습니다.

 

화면 구성


1. Time.timeScale 값을 변경하기

 

-. Text 오브젝트인 ' Timer1 ' 에 아래의 스크립터를 만들어서 넣도록 하겠습니다.

 

 

using System.Collections;
using UnityEngine;
using UnityEngine.UI;

public class TestTimer : MonoBehaviour
{
    float tstTime;//총 흐른 시간
    int tstMsec; //밀리 초 시간
    int tstSec; //초 시간
    int tstMin; //분 시간  

    public GameObject testCube;
  
    private void Start()
    {       
       StartCoroutine("TimerGo"); //코루틴 시간
    }
       
    IEnumerator TimerGo() //코루틴함수
    {
        while (true)
        {
            tstTime += Time.deltaTime; //총흐른 시간
            tstMsec = (int)((tstTime - (int)tstTime) * 100); //밀리 초 계산
            tstSec = (int)(tstTime % 60); // 초 계산
            tstMin = (int)(tstTime / 60 % 60); //분 계산

            GetComponent<Text>().text = string.Format("{0:00}:{1:00}:{2:00}", tstMin, tstSec, tstMsec); // 흐른시간을 텍스트에 표시함

            if (Input.GetKey(KeyCode.A)) // A 키를 누르면
            {
                Time.timeScale = 0.0f; // 시간을 정지시킴
            }
            else if (Input.GetKey(KeyCode.B)) // B 키를 누르면
            {
                Time.timeScale = 0.1f; // 시간을 느리게 흐르게 함
            }
            else //키를 누르지 않으면
            {
                Time.timeScale = 1.0f; // 시간을 원래 시간의 흐름으로 되돌림
            }

            testCube.transform.Rotate(new Vector3(0, 1, 0)*180*Time.deltaTime); //큐브를 회전 시킴        

            yield return null;
        }
    }
}

 

-. 그리고, TestCube 게임오브젝트를 드래그앤드랍으로 스크립터 변수에 넣어서 연결합니다.

 

TestCube 게임오브젝트 연결

 

-. Text 오브젝트인 ' Timer2 ' 에는 아래의 스크립터를 만들어서 넣도록 하겠습니다.

 

 

using System.Collections;
using UnityEngine;
using UnityEngine.UI;

public class TestTimer2 : MonoBehaviour
{
    float tstTime;//총 흐른 시간
    int tstMsec; //밀리 초 시간
    int tstSec; //초 시간
    int tstMin; //분 시간  

    public GameObject testCube2;
  
    private void Start()
    {       
       StartCoroutine("TimerGo"); //코루틴 시간
    }
       
    IEnumerator TimerGo() //코루틴함수
    {
        while (true)
        {
            tstTime += Time.deltaTime; //총흐른 시간  
            tstMsec = (int)((tstTime - (int)tstTime) * 100); //밀리 초 계산
            tstSec = (int)(tstTime % 60); // 초 계산
            tstMin = (int)(tstTime / 60 % 60); //분 계산

            GetComponent<Text>().text = string.Format("{0:00}:{1:00}:{2:00}", tstMin, tstSec, tstMsec); // 흐른시간을 텍스트에 표시함

            testCube2.transform.Rotate(new Vector3(0, 1, 0) * 180 * Time.deltaTime);//큐브를 회전 시킴

            yield return null;
        }
    }
}

 

 

-. 그리고, 앞에서와 마찬가지로 TestCube2 게임오브젝트를 드래그앤드랍으로 스크립터 변수에 넣어서 연결합니다.

 

TestCube2 게임오브젝트 연결

 

-. 실행보면 아래와 같이 되는 것을 확인 할 수있습니다.

 

timeScale 예제

-. 실행해보면 중간에 ' A ' 키를 누르면 시간이 정지하고 다시 놓으면 정상적으로 시간이 흐르는 것을 확인 할 수 있습니다. 그리고, ' B ' 키를 누르면 천천히 시간이 흐르면서 큐브의 회전도 느려지는 것을 확인 할 수 있습니다.

 

timeScale 예제2

 


2. Time.unscaledDeltaTime 을 적용해보기

 

Time.timeScale 의 속성값의 변화에 영향을 받지 않도록 하기위해서 사용하는 방법 중에 하나가 unscaledDeltaTime 속성입니다. 그럼, 어떻게 동작하는지 알아보겠습니다.

 

 

-. Text 오브젝트인 ' Timer2 ' 에는 아래와 같이 스크립터를 수정해보도록 하겠습니다.

 

using System.Collections;
using UnityEngine;
using UnityEngine.UI;

public class TestTimer2 : MonoBehaviour
{
    float tstTime;//총 흐른 시간
    int tstMsec; //밀리 초 시간
    int tstSec; //초 시간
    int tstMin; //분 시간  

    public GameObject testCube2;
  
    private void Start()
    {       
       StartCoroutine("TimerGo"); //코루틴 시간
    }
       
    IEnumerator TimerGo() //코루틴함수
    {
        while (true)
        {
            tstTime += Time.unscaledDeltaTime; //총흐른 시간  
            tstMsec = (int)((tstTime - (int)tstTime) * 100); //밀리 초 계산
            tstSec = (int)(tstTime % 60); // 초 계산
            tstMin = (int)(tstTime / 60 % 60); //분 계산

            GetComponent<Text>().text = string.Format("{0:00}:{1:00}:{2:00}", tstMin, tstSec, tstMsec); // 흐른시간을 텍스트에 표시함

            testCube2.transform.Rotate(new Vector3(0, 1, 0) * 180 * Time.unscaledDeltaTime);//큐브를 회전 시킴

            yield return null;
        }
    }
}

 

-. 실행보면  중간에 ' A ' 키를 누르면 아래와 같이 왼쪽만 정지하고 오른쪽은 그대로 시간이 계속 흐른다는 것을 확인 할 수있습니다. 이 처럼 unscaledDeltaTime 속성은 멀티버스세상의 전혀 딴 세상처럼 따로 시간이 흘러간다고 보면 되겠습니다.

 

unscaledDeltaTime 예제

 


 

Time.timeScale 속성을 변경하는 경우는 게임을 만들면서 생각보다 많이는 없습니다. 왜냐하면, 오브젝터의 회전값을 변경하게 되는 경우는 시간을 건드리는 것 보다 회전 수치를 조정하는 것이 더 효과적이고, 캐릭터의 움직임을 슬로우로 표현하고 싶은 경우에는 애니메이션의 속성값인 animator.speed값을 조정하는게 편합니다. 그래도, 다양한 방법을 아는 것은 힘이겠죠? ㅋㅋ


그럼 오늘도 즐유!(즐거운 유니티) ^^