Unity의 시간(Time)

응애개발자·2024년 5월 5일

Unity 개념 정리

목록 보기
1/7
post-thumbnail

Unity에서 시간(Time)은 움직이는 모든 것과 네트워크 및 쉐이더 등 여러 곳에서 사용된다.

그 중 FixedUpdate, Update, LateUpdate에 대해 알아보았다.

FixedUpdate

  • FixedUpdate는 기본적으로 0.02초마다(1초에 50번) 일정한 간격으로 호출되는 함수이다. 호출간격은 Unity 내에서 바꿔줄 수 있다.
  • FixedUpdate는 Update 이전에 호출되며, 물리적인 계산을 할 때 주로 사용된다.

여기까지 봤을때는 무조건 0.02초에 한번씩 호출될 것 같았는데

void FixedUpdate(){
	time = Time.realtimeSinceStartup - time;
	Debug.Log("FixedUpdate 간격: "+ time);
	time = Time.realtimeSinceStartup;
}

막상 이런식으로 로그를 찍어보면 간격이 조금 오락가락 한다.

로그의 맨 밑의 1초당 FixedUpdate 호출 수가 50으로 찍히는 것을 보면 무조건 일정한 간격으로 호출한다기보단

"최대한 0.02초 간격으로 호출해서 최종적으로 1초에 50번 호출할 수 있도록 노력한다"
정도로 보였다.

( 추후에 나오는 Time.deltaTime을 로그로 찍어봤을땐 정확히 0.02초가 나와서 혼란스러운 상태이다. 아무래도 더 알아봐야 할 것 같다. )


Update & LateUpdate

  • Update와 LateUpdate는 프레임당 한번씩 호출되는 함수이다. 60 FPS(Frame Per Second)라면 평균적으로 1초에 60번 호출된다는 것을 의미한다. 물론 이것도 평균이므로 정확히 1초에 60개의 프레임이 렌더링되는 것을 보장하지는 않는다.

  • Update와 LateUpdate는 작동 방식이 같지만 LateUpdate는 Update함수가 호출된 후에 호출된다는 호출 시점의 차이가 있다.

LateUpdate는 카메라 추적에 자주 사용된다고 한다.
캐릭터의 이동을 카메라가 따라간다고 가정했을 때,
Update에서 캐릭터를 이동시키고 LateUpdate에서 캐릭터의 최종위치로 카메라의 위치를 이동시키는 방식으로 사용하는 것 같다.

로그를 봐도 Update가 먼저 호출되고 LateUpdate가 호출되는 것을 볼 수 있다.



시간에 따른 이동 정규화

1초당 0.1m를 이동하는 코드와 FixedUpdate, Update, LateUpdate의 매 반복당 0.1m를 이동하는 코드를 작성해 적용해보았다.

예시 코드

void Update()
{
	transform.Translate(0.1f, 0, 0);
}

위에서부터

  1. 1초당 0.1m 이동
  2. FixedUpdate : 반복당 0.1m 이동
  3. Update : 반복당 0.1m 이동
  4. LateUpdate : 반복당 0.1m 이동

이다.

가장 위의 구가 1초에 0.1m 씩 움직이는데에 반해
FixedUpdate는 대략 0.02 초에 한번씩, 밑의 Update와 LateUpdate는 60FPS 기준 대략 0.0166 초에 한번씩 0.1m를 움직이기 때문에 매우 빠른 속도로 움직이는 것을 볼 수 있다.

만약 이를 모두 같은 속도로 움직이게 하고 싶다면 Time.deltaTime을 사용해야 한다.


Time.deltaTime

  • Time.deltaTime은 이전 프레임에서 현재 프레임까지 걸린 시간이다.

예를 들어, 30fps 로 동작하는 Update와 LateUpdate가 있다고 할때 1초에 30개의 프레임이 지나가므로 프레임 사이의 시간은 대략 1/30초일 것이다. 따라서 Time.deltaTime은 평균적으로 1/30초이다.

그럼 매 프레임마다 Time.deltaTime 값인 1/30m 만큼 이동한다면?
1/30 초마다 1/30m 씩 움직이므로 이를 30번 반복하게 되면
1초에 1m를 움직이게 될 것이다.

이를 이용해 서로 다른 fps를 가진 플레이어들의 이동속도를 같게 만들 수 있다!

( 원래는 프레임당 0.1m 씩 이동을 시키면 30fps 에서는 1초에 3m를 이동하고 60fps 에서는 1초에 6m 를 이동해서 프레임이 낮은 유저는 눈물을 흘려야 하는 문제가 발생한다. )

매 프레임마다 Time.deltaTime 만큼 움직인다면 60fps로 동작하는 장치에서는 1/60 초마다 1/60m 씩 움직이게 되므로
결국 이도 1초에 1m 움직이게 되기 때문이다.

이것은 FixedUpdate도 마찬가지인데, FixedUpdate의 Time.deltaTime 값은 기본적으로 0.02초로 Time.deltaTime 만큼 움직이게 하면
0.02초에 0.02m 씩 움직여 1초에 1m를 움직이게 된다.

이런식으로 FixedUpdate, Update, LateUpdate의 이동을 초당 1m 이동으로 바꿔보았다.

예시 코드

void Update()
{
	transform.Translate(Time.deltaTime, 0, 0);
}

모두 초속 1m로 같은 속도로 움직이는 것을 볼 수 있다.



정리

간단하게 FixedUpdate와 Update, LateUpdate에 알아보고 Time.deltaTime에 대해서도 알아보았다.
뉴비의 공부용 글이라 틀린곳이 있을 수 있으니 이상한 곳을 짚어준다면 정말 감사할것이다.

참고한 강의

unity.com/tutorial/time

0개의 댓글