본문 바로가기

Unity

Unity - Pause 버튼 구현하기(Time.scaleTime)

예시는 아래와 같음

Pause Button

 

 

구현하기

1. Time.timeScale 이용하기

 

Time.timeScale이란 아래와 같음

https://docs.unity3d.com/ScriptReference/Time-timeScale.html

슬로우모션이나 더욱빠르게, 혹은 멈추게 할 수 있음

 

즉, 버튼을 누른 순간 Time.timeScale = 0; 해주면 됨

 

 

 

2. Button으로 상호작용하기

 

1) Button에 있는 컴포넌트에 OnClick에 달아줄 함수를 만들어줌 (본인은 그냥 한곳에 몰아넣음)

 

2) 또한 플레이어는 움직여야 하므로 Update문에서 Translate() 해줌

 

전체 코드는 아래와 같음

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
 
public class Player : MonoBehaviour
{
    public Text pauseText;
    void Update()
    {
        Debug.Log("Update");
        transform.Translate(Time.deltaTime, 00);
    }
    private void FixedUpdate()
    {
        Debug.Log("FixedUpdate");
    }
 
    public void OnTogglePauseButton()
    {
        if (Time.timeScale == 0) //멈춰있으면
        {
            Time.timeScale = 1f; //시작
            pauseText.text = "Pause";
        }
        else //움직이면
        {
            Time.timeScale = 0; //멈추기
            pauseText.text = "Resume";
        }
    }
}
cs

 

위의 코드에서 유의해서 볼것은 Update()와 FixedUpdate()임

 

위의 코드대로 실행하면 Time.timeScale이 0 이어도 Update()의 로그는 찍힘

그럼 Update()는 Time.timeScale = 0 이어도 실행되는데 왜 Player는 멈춰있을까?

-> Update()을 보면 Player의 움직임을 Time.deltaTime을 이용해서 사용했기 때문

-> timeScale은 다른 시간과 델타시간에도 영향을 준다고 함

-> 그래서 Time.deltaTime도 0임

유니티 스크립팅 설명

 

 

3. Update vs FixedUpdate

 

Time.timeScale = 0; 일때 Update()는 실행되고 FixedUpdate는 실행되지 않음

 

http://developug.blogspot.com/2014/09/update-fixedupdate-lateupdate.html

 

Update는 프레임마다 호출이며, FixedUpdate는 독립적인 타이머가 존재하여 그때마다 호출임

Update :        timescale에 독립적 framerate에 의존적 

FixedUpdate : timescale에 의존적 framerate에 독립적 

 

이러하여 timeScale이 0이어도 Update는 실행되고 FixedUpdate는 실행되지 않음

 

그럼 Update문 안에서 멈추게 하려면 어떻게 해야할까?

1) if ( timescale == 0 ) return;

2) Time.deltaTime 사용

 

 

 

4. Coroutine에서는?

 

Coroutine에서 사용되는

yield return new WaitForSeconds(); 는 흔히 봤을 것

WaitForSeconds()는 timescale에 의존적

즉, timescale이 0이라면 WaitForSeconds을 사용하는 코루틴은 멈춤

 

그럼 만약 Coroutine을 실행시키고 싶으면

yield return new WaitForSecondsRealtime(); 사용하면 됨

 

또한 코루틴이 timescale로 인해 멈추고 다시 시작될 때 멈춘부분부터 다시 진행함

 

 

 

 

5. 정리

 

1) Time.timeScale = 0으로 timescale에 의존하는 함수는 멈춤

2) Update는 멈추지 않음 / FixedUpdate는 멈춤

3) Update에 조건문이나 Time.deltaTime으로 제어할 수 있음

4) Coroutine에서 WaitForSeconds 는 멈추고 WaitForSecondsRealtime은 멈추지 않음

 

 

 

 

 

 

===참고===

 

FixedUpdate()는 물리구현에서 많이 사용하라 함(일정한 시간간격)

-> velocity같은 rigidbody를 Update에서 사용하지 말것

Time.deltaTime은 가변적인 값이지만 타이머 같은 것은 FixedUpdate에서 사용해도 괜찮다고 함

Time.fixedDeltaTime은 0.02로 고정임

 

Q) rigidbody는 update를 따르는가 fixedupdate를 따르는 가

Q) timescale이 0이면 어떤함수부터 실행하지 않는가