개발단에 가입하여 베르의 게임 개발 유튜브를 후원해주세요! https://www.youtube.com/channel/UC9j37A2ACL9ooSbsT4mtGww/join

 

안녕하세요! 여러분들과 함께 게임 개발을 공부하는 베르입니다!

이번 강좌에서는 유니티 엔진에서 시간과 관련된 프로퍼티들을 제공하는 Time 클래스의 주요 프로퍼티에 대해서 알아봅시다. 본 강좌는 이전에 올라온 Time 클래스 관련 강좌를 하나로 묶은 것입니다.

 

사용 엔진 버전 : 2020.3

 

타임라인

0:00 인트로

0:11 detaTime

3:03 timeScale

4:37 unscaledDeltaTime

6:10 time

7:27 realtimeSinceStartup

8:53 timeSinceLevelLoad

9:56 아웃트로

 

[투네이션 후원]

https://toon.at/donate/637735212761460238

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

- 유니티 에셋스토어 : https://prf.hn/click/camref:1100lkbzf/creativeref:1101l61541

 

[디스코드 채널]

https://discord.gg/tqmRTy4pgk

 

스크립트

인트로

안녕하세요. 여러분들과 함께 게임 개발을 공부하는 베르입니다.

이번에는 유니티 엔진에서 시간과 관련된 값들을 제공해주는 Time 클래스의 프로퍼티들에 대해서 알아보겠습니다.

deltaTime

제일 먼저 설명할 프로퍼티는 deltaTime 입니다.

먼저 deltaTime에서 delta는 보통 값의 차이를 의미하는 단어입니다.

시간을 의미하는 Time과 조합해서 생각해보면 deltaTime은 차이가 나는 시간이라는 뜻으로 지난 프레임이 완료되는 데까지 걸린 시간 차이를 의미하며 단위는 초 단위입니다.

한마디로 한 프레임을 진행하는데 걸린 시간이라는 뜻이죠.

그래서 게임을 진행하다가 컴퓨터 사양이나 게임의 최적화 문제로 게임의 프레임이 떨어지는 프레임 드랍 현상이 일어나면 이 deltaTime 값은 한 프레임의 화면을 렌더링하는데 걸리는 시간만큼 커지게 됩니다.

보통 30프레임 기준의 게임에서는 한 프레임당 deltaTime이 0.033정도가 나와야하고 60프레임 기준의 게임에서는 한 프레임당 0.016 정도가 나와야 합니다.

유니티 에디터에서 스크립트를 하나 생성하고 Start 함수에서 Application.targetFrameRate를 30으로 지정한 다음 Update 함수에서 Time.deltaTime을 디버그로 출력시키도록 코드를 작성합니다.

코드를 모두 작성한 다음에는 코드를 저장하고 에디터로 돌아가서 아무 게임 오브젝트에나 방금 만든 컴포넌트를 붙이고 게임을 실행해보면 앞에서 말한대로 약 0.033초에 가까운 값이 매 프레임마다 갱신되는 것을 볼 수 있습니다.

그리고 다시 스크립트에서 targetFrameRate를 60으로 변경하고 에디터로 돌아가서 테스트해보면 0.016초에 가깝게 deltaTime 값이 나오는 것을 확인할 수 있습니다.

그럼 이 delta time은 어디에 사용될까요?

그 예시를 보여드리도록 하겠습니다.

먼저 Update 함수에서 W키를 누르면 오브젝트를 이동시키는 코드를 작성해보겠습니다.

이 때 이동 코드에서 캐릭터의 이동 방향과 속도만 이용해서 캐릭터를 이동시키면 문제가 발생하게됩니다.

이 비교 영상처럼 프레임이 10일 때와 60일 때 캐릭터가 다른 속도로 움직이게 되는 겁니다.

이 문제의 원인은 프레임이 10일 때는 1초에 캐릭터를 10번 움직이게 되고, 프레임이 60일 때는 1초에 캐릭터를 60번 움직이기 때문입니다.

좀 더 풀어서 설명해보자면 이 코드에서는 프레임이 10일 때는 1의 속도로 캐릭터를 1초동안 10번 움직이기 때문에 이동한 거리가 10이 되는 것이고, 프레임이 60일 때는 1의 속도로 캐릭터를 1초동안 60번 움직이기 때문에 이동한 거리가 60이 됩니다.

1초 동안 움직인 횟수가 달라서 움직인 거리 역시 달라지는 것이죠.

이것은 컴퓨터의 성능이 오브젝트의 속도에 영향을 미치게 되는 것으로 보통의 게임에서는 발생해서는 안되는 문제입니다.

이 문제를 해결하기 위한 방법이 바로 이 이동 값에 delta time을 곱해주는 겁니다.

이렇게 이동 벡터에 delta time을 곱해주고 나면, 게임이 몇 프레임으로 진행되는지에 전혀 상관없이 오브젝트는 동일한 속도로 움직이게 됩니다.

이런 식으로 이동이나 회전 등 움직임에 있어서 시간의 영향을 받는 기능을 만들 때는 값에 deltaTime을 곱해서 흘러간 프레임 시간만큼만 가중치를 줌으로써 프로세서 속도의 영향에서 자유로워 지게됩니다.

timeScale

그 다음 프로퍼티는 timeScale 입니다.

time scale라는 프로퍼티의 이름을 단순하게 번역해보면 시간의 크기라는 뜻입니다.

이 값을 조절하면 시간이 흐르는 속도를 조절하여 시간이 빠르게 흐르거나 느리게 흐르게 만들 수 있습니다.

C# 스트립트를 하나 생성하고 스크립트 에디터를 엽니다.

스크립트 에디터가 열리고 나면 float 타입으로 timer 변수를 만들어줍니다.

그리고 Update 함수에서 timer 변수에 deltaTime 값을 누적시키며 더하고 그 timer 변수를 이용해서 오브젝트가 Sin 그래프를 따라서 움직이게 만들어 줍니다.

그 아래에는 키보드 화살 키를 눌러서 timeScale를 늘리거나 줄이는 코드를 작성합니다.

그리고 숫자 1을 누르면 timeScale를 1로 만들도록 해줍니다.

코드를 모두 작성한 다음에는 코드를 저장하고 에디터로 이동합니다.

에디터로 이동한 다음에는 큐브 오브젝트를 생성하고 방금 만든 컴포넌트를 붙여줍니다.

이제 게임을 플레이시켜 보겠습니다.

게임이 시작되면 큐브가 왕복으로 움직이는 모습을 볼 수 있는데 이때 위쪽 화살표 키를 누르면 time scale이 커지면서 큐브의 움직임이 빨라집니다.

반대로 아래쪽 화살표 키를 누르면 time scale이 작아지면서 큐브의 움직임이 느려집니다.

그러다가 time scale이 0이 되면 움직임이 완전히 멈춥니다.

그리고 숫자 1 키를 누르면 time scale이 1이 되면서 원래의 속도로 움직입니다.

이런 식으로 time scale을 조절해서 슬로우 모션같은 연출을 할 수 있습니다.

unscaledDeltaTime

그 다음 알아볼 프로퍼티는 unscaledDeltaTime입니다.

delta time에 대해서 설명했을 때 이야기한 것처럼 delta time은 게임에서 플레이어의 입력과 게임 처리, 화면 렌더링 등의 작업이 한 번 처리되고 그 결과물이 플레이어의 모니터에 그려지는 한 프레임이 진행되는 시간을 의미합니다.

이 delta time에 unscaled를 붙임으로써 크기가 바뀌지 않은 delta time을 의미하게 됩니다.

time scale의 영향을 받지 않는 delta time인 것이죠.

새 C# 스크립트를 생성하고 앞에서 만든 컴포넌트에서 오브젝트를 이동시키는 코드를 복사해서 Update 함수에 붙여넣어줍니다.

그리고 timer에 더해주는 값을 deltaTime에서 unscaledDeltaTime으로 바꿔줍니다.

코드를 모두 작성한 다음에는 저장하고 에디터로 돌아갑니다.

그리고 씬에 새로운 3D 오브젝트를 배치하고 거기에 새로 만든 컴포넌트를 붙여줍니다.

그 다음 게임을 플레이시키면 거의 비슷한 속도로 움직이는 두 오브젝트가 보일 겁니다.

이 때 화살표 키를 눌러서 time scale을 조절하면 delta time으로 움직이는 오브젝트의 속도는 time scale의 영향을 받아 느려지거나 빨라지지만, unscaled delta time으로 움직이는 오브젝트의 속도는 전혀 영향을 받지 않고 동일한 속도로 움직이는 것을 볼 수 있습니다.

이런 식으로 어떤 오브젝트의 움직임이 time scale의 영향을 받지 않기를 원할 때는 unscaled delta time을 사용해야 합니다.

time scale과 delta time, unscaled delta time을 적절하게 조합해서 사용하면 특수한 스킬로 적들은 멈춰있거나 느려졌는데 플레이어만 정상적인 속도로 움직이는 기능을 연출할 수 있습니다.

time

그 다음 프로퍼티를 설명하기 전에 씬을 하나 새로 생성합니다.

Time 클래스의 프로퍼티인 time은 게임이 시작된 이후로부터 흐른 시간을 보여주는 프로퍼티입니다.

유니티 에디터에서 새 C# 클래스를 생성하고 스크립트 에디터를 열어줍니다.

비주얼 스튜디오가 열리고 나면 클래스의 상단에 UnityEngine.UI 네임스페이스를 using 선언해줍니다.

그리고 Text 타입으로 측정한 시간을 보여줄 timeText 변수를 선언해줍니다.

그 다음 Update 함수에서는 Time.time 값을 문자열로 만들어서 timeText로 출력하는 코드를 작성합니다.

코드를 모두 작성한 다음에는 코드를 저장하고 에디터로 돌아갑니다.

에디터에서는 Hierarchy 뷰에 우클릭해서 [UI > Text] 항목을 선택해서 텍스트 UI를 생성합니다.

그리고 Canvas 게임오브젝트에 방금 만든 컴포넌트를 붙인 뒤 Time Text 프로퍼티에 방금 만든 텍스트 UI를 할당해줍니다.

그 다음 게임을 플레이해보면 게임이 시작된 이후에 흐른 시간이 계속해서 올라가는 모습을 볼 수 있습니다.

realtimeSinceStartup

그 다음에 설명할 프로퍼티는 realtimeSinceStartup입니다.

이 realtimeSinceStartup 역시 time과 같이 게임이 시작된 이후로부터 흐른 시간을 보여주는 프로퍼티입니다.

그럼 이 realtimeSinceStartup 프로퍼티가 time 프로퍼티와 어떤 차이가 있는지 알아보겠습니다.

다시 스크립트로 돌아가서 Time.time을 출력하는 timeText에 realtimeSinceStartup도 함께 출력하도록 코드를 수정합니다.

그리고 키보드 화살표 키로 timeScale을 조절할 수 있는 코드를 작성합니다.

코드를 모두 수정한 다음에는 에디터로 돌아갑니다.

에디터로 돌아온 다음 게임을 플레이해보면 게임이 시작된 이후로 흐른 시간이 Time.time과 Time.realtimeSinceStartup 프로퍼티를 통해서 출력됩니다.

이 때 키보드의 화살표 키를 눌러서 time scale을 조절해보면 Time.time은 time scale 값에 따라 영향을 받지만 realtimeSinceStartup은 전혀 영향을 받지 않는 모습을 볼 수 있습니다.

거기에 추가로 게임을 잠시 일시정지시켰다가 플레이시켜보면 realtimeSinceStartup은 일시정지한 시간이 포함되어 값이 바뀐 것을 확인할 수 있습니다.

이렇게 게임이 시작된 시간 값을 출력하는 기능은 쓸데가 별로 없어보이지만, 게임을 실행한 시간을 기록해서 플레이어에게 업적을 준다던지, 너무 많은 시간동안 게임을 플레이하고 있는 유저가 있다면 경고문을 출력해주는 기능에 사용할 수 있습니다.

timeSinceLevelLoad

그리고 마지막으로 알아볼 프로퍼티는 timeSinceLevelLoad입니다.

이 프로퍼티는 마지막으로 씬이 로드된 이후로 흐른 시간을 의미합니다.

스크립트로 돌아가서 timeText에 timeSinceLevelLoad를 출력하는 코드를 추가합니다.

그리고 스크립트 상단에 UnityEngine.SceneManagement 네임스페이스를 using 선언하고 Update 함수에서 스페이스 키를 누르면 현재 씬을 다시 로드하도록 코드를 작성합니다.

코드를 모두 작성한 다음에는 코드를 저장하고 에디터로 돌아갑니다.

에디터에서는 빌드 세팅 창을 열어서 현재 씬을 Scenes In Build 목록에 추가해줍니다.

그 다음에 게임을 플레이해보면 time과 realtimeSinceStartup, 그리고 timeSinceLevelLoad 값이 동시에 상승하는 것을 확인할 수 있습니다.

이 때 스페이스 키를 누르면 현재 씬이 다시 로드되는데 time과 realtimeSinceStartup은 누적된 상태로 계속 증가하지만 timeSinceLevelLoad 값은 초기화되어서 0부터 다시 누적되는 모습을 볼 수 있습니다.

이 프로퍼티를 이용하면 던전 씬에 진입하고 난 이후에 플레이어가 던전을 클리어하는데 걸린 시간을 측정할 수 있습니다.

아웃트로

이번 영상에서는 Time 클래스의 여러 가지 프로퍼티에 대해서 알아보았습니다.

이 강좌는 구독자 여러분들의 시청과 후원으로 제작되었습니다.

이상 베르의 게임 개발 유튜브였습니다. 감사합니다.

반응형

개발단에 가입하여 베르의 게임 개발 유튜브를 후원해주세요! https://www.youtube.com/channel/UC9j37A2ACL9ooSbsT4mtGww/join

 

안녕하세요! 여러분들과 함께 게임 개발을 공부하는 베르입니다!

이번에는 Time 클래스의 프로퍼티 중에서 time, realtimeSinceStartup, timeSinceLevelLoad에 대해서 알아보겠습니다.

 

사용 엔진 버전 : 2020.3

 

타임라인

0:00 인트로

0:14 Time.time

1:21 Time.realtimeSinceStartup

2:47 Time.timeSinceLevelLoad

3:57 아웃트로

 

[투네이션 후원]

https://toon.at/donate/637735212761460238

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

- 유니티 에셋스토어 : https://prf.hn/click/camref:1100lkbzf/creativeref:1101l61541

 

스크립트

인트로

안녕하세요. 여러분들과 함께 게임 개발을 공부하는 베르입니다.

이번에는 Time 클래스의 프로퍼티 중에서 time과 realtimeSinceStartup, 그리고 timeSinceLevelLoad에 대해서 알아보도록 하겠습니다.

Time.time

Time 클래스의 프로퍼티인 time은 게임이 시작된 이후로부터 흐른 시간을 보여주는 프로퍼티입니다.

유니티 에디터에서 새 C# 클래스를 생성하고 스크립트 에디터를 열어줍니다.

비주얼 스튜디오가 열리고 나면 클래스의 상단에 UnityEngine.UI 네임스페이스를 using 선언해줍니다.

그리고 Text 타입으로 측정한 시간을 보여줄 timeText 변수를 선언해줍니다.

그 다음 Update 함수에서는 Time.time 값을 문자열로 만들어서 timeText로 출력하는 코드를 작성합니다.

코드를 모두 작성한 다음에는 코드를 저장하고 에디터로 돌아갑니다.

에디터에서는 Hierarchy 뷰에 우클릭해서 [UI > Text] 항목을 선택해서 텍스트 UI를 생성합니다.

그리고 Canvas 게임오브젝트에 방금 만든 컴포넌트를 붙인 뒤 Time Text 프로퍼티에 방금 만든 텍스트 UI를 할당해줍니다.

그 다음 게임을 플레이해보면 게임이 시작된 이후에 흐른 시간이 계속해서 올라가는 모습을 볼 수 있습니다.

Time.realtimeSinceStartup

그 다음에 설명할 프로퍼티는 realtimeSinceStartup입니다.

이 realtimeSinceStartup 역시 time과 같이 게임이 시작된 이후로부터 흐른 시간을 보여주는 프로퍼티입니다.

그럼 이 realtimeSinceStartup 프로퍼티가 time 프로퍼티와 어떤 차이가 있는지 알아보겠습니다.

다시 스크립트로 돌아가서 Time.time을 출력하는 timeText에 realtimeSinceStartup도 함께 출력하도록 코드를 수정합니다.

그리고 키보드 화살표 키로 timeScale을 조절할 수 있는 코드를 작성합니다.

코드를 모두 수정한 다음에는 에디터로 돌아갑니다.

에디터로 돌아온 다음 게임을 플레이해보면 게임이 시작된 이후로 흐른 시간이 Time.time과 Time.realtimeSinceStartup 프로퍼티를 통해서 출력됩니다.

이 때 키보드의 화살표 키를 눌러서 time scale을 조절해보면 Time.time은 time scale 값에 따라 영향을 받지만 realtimeSinceStartup은 전혀 영향을 받지 않는 모습을 볼 수 있습니다.

거기에 추가로 게임을 잠시 일시정지시켰다가 플레이시켜보면 realtimeSinceStartup은 일시정지한 시간이 포함되어 값이 바뀐 것을 확인할 수 있습니다.

이렇게 게임이 시작된 시간 값을 출력하는 기능은 쓸데가 별로 없어보이지만, 게임을 실행한 시간을 기록해서 플레이어에게 업적을 준다던지, 너무 많은 시간동안 게임을 플레이하고 있는 유저가 있다면 경고문을 출력해주는 기능에 사용할 수 있습니다.

Time.timeSinceLevelLoad

그리고 마지막으로 알아볼 프로퍼티는 timeSinceLevelLoad입니다.

이 프로퍼티는 마지막으로 씬이 로드된 이후로 흐른 시간을 의미합니다.

스크립트로 돌아가서 timeText에 timeSinceLevelLoad를 출력하는 코드를 추가합니다.

그리고 스크립트 상단에 UnityEngine.SceneManagement 네임스페이스를 using 선언하고 Update 함수에서 스페이스 키를 누르면 현재 씬을 다시 로드하도록 코드를 작성합니다.

코드를 모두 작성한 다음에는 코드를 저장하고 에디터로 돌아갑니다.

에디터에서는 빌드 세팅 창을 열어서 현재 씬을 Scenes In Build 목록에 추가해줍니다.

그 다음에 게임을 플레이해보면 time과 realtimeSinceStartup, 그리고 timeSinceLevelLoad 값이 동시에 상승하는 것을 확인할 수 있습니다.

이 때 스페이스 키를 누르면 현재 씬이 다시 로드되는데 time과 realtimeSinceStartup은 누적된 상태로 계속 증가하지만 timeSinceLevelLoad 값은 초기화되어서 0부터 다시 누적되는 모습을 볼 수 있습니다.

이 프로퍼티를 이용하면 던전 씬에 진입하고 난 이후에 플레이어가 던전을 클리어하는데 걸린 시간을 측정할 수 있습니다.

아웃트로

이번 영상에서는 Time 클래스의 프로퍼티 중에서 time과 realtimeSinceStartup, 그리고 timeSinceLevelLoad에 대해서 알아보았습니다.

이 강좌는 구독자 여러분들의 시청과 후원으로 제작되었습니다.

이상 베르의 게임 개발 유튜브였습니다. 감사합니다.

반응형

 

개발단에 가입하여 베르의 게임 개발 유튜브를 후원해주세요! https://www.youtube.com/channel/UC9j37A2ACL9ooSbsT4mtGww/join

 

안녕하세요! 여러분들과 함께 게임 개발을 공부하는 베르입니다!

이번에는 Time 클래스의 프로퍼티 중에서 timeScale과 unscaledDeltaTime에 대해서 알아봅시다!

 

사용 엔진 버전 : 2020.3

 

타임라인

0:00 인트로

0:10 Time.timeScale

1:40 Time.unscaledDeltaTime

3:14 아웃트로

 

스크립트

인트로

안녕하세요. 여러분들과 함께 게임 개발을 공부하는 베르입니다.

이번에는 Time 클래스의 프로퍼티인 timeScale과 unscaledDeltaTime에 대해서 알아보겠습니다.

Time.timeScale

time scale라는 프로퍼티의 이름을 단순하게 번역해보면 시간의 크기라는 뜻입니다.

이 값을 조절하면 시간이 흐르는 속도를 조절하여 시간이 빠르게 흐르거나 느리게 흐르게 만들 수 있습니다.

C# 스트립트를 하나 생성하고 스크립트 에디터를 엽니다.

스크립트 에디터가 열리고 나면 float 타입으로 timer 변수를 만들어줍니다.

그리고 Update 함수에서 timer 변수에 deltaTime 값을 누적시키며 더하고 그 timer 변수를 이용해서 오브젝트가 Sin 그래프를 따라서 움직이게 만들어 줍니다.

그 아래에는 키보드 화살 키를 눌러서 timeScale를 늘리거나 줄이는 코드를 작성합니다.

그리고 숫자 1을 누르면 timeScale를 1로 만들도록 해줍니다.

코드를 모두 작성한 다음에는 코드를 저장하고 에디터로 이동합니다.

에디터로 이동한 다음에는 큐브 오브젝트를 생성하고 방금 만든 컴포넌트를 붙여줍니다.

이제 게임을 플레이시켜 보겠습니다.

게임이 시작되면 큐브가 왕복으로 움직이는 모습을 볼 수 있는데 이때 위쪽 화살표 키를 누르면 time scale이 커지면서 큐브의 움직임이 빨라집니다.

반대로 아래쪽 화살표 키를 누르면 time scale이 작아지면서 큐브의 움직임이 느려집니다.

그러다가 time scale이 0이 되면 움직임이 완전히 멈춥니다.

그리고 숫자 1 키를 누르면 time scale이 1이 되면서 원래의 속도로 움직입니다.

이런 식으로 time scale을 조절해서 슬로우 모션같은 연출을 할 수 있습니다.

Time.unscaledDeltaTime

그 다음 알아볼 프로퍼티는 unscaledDeltaTime입니다.

delta time에 대해서 설명했을 때 이야기한 것처럼 delta time은 게임에서 플레이어의 입력과 게임 처리, 화면 렌더링 등의 작업이 한 번 처리되고 그 결과물이 플레이어의 모니터에 그려지는 한 프레임이 진행되는 시간을 의미합니다.

이 delta time에 unscaled를 붙임으로써 크기가 바뀌지 않은 delta time을 의미하게 됩니다.

time scale의 영향을 받지 않는 delta time인 것이죠.

새 C# 스크립트를 생성하고 앞에서 만든 컴포넌트에서 오브젝트를 이동시키는 코드를 복사해서 Update 함수에 붙여넣어줍니다.

그리고 timer에 더해주는 값을 deltaTime에서 unscaledDeltaTime으로 바꿔줍니다.

코드를 모두 작성한 다음에는 저장하고 에디터로 돌아갑니다.

그리고 씬에 새로운 3D 오브젝트를 배치하고 거기에 새로 만든 컴포넌트를 붙여줍니다.

그 다음 게임을 플레이시키면 거의 비슷한 속도로 움직이는 두 오브젝트가 보일 겁니다.

이 때 화살표 키를 눌러서 time scale을 조절하면 delta time으로 움직이는 오브젝트의 속도는 time scale의 영향을 받아 느려지거나 빨라지지만, unscaled delta time으로 움직이는 오브젝트의 속도는 전혀 영향을 받지 않고 동일한 속도로 움직이는 것을 볼 수 있습니다.

이런 식으로 어떤 오브젝트의 움직임이 time scale의 영향을 받지 않기를 원할 때는 unscaled delta time을 사용해야 합니다.

time scale과 delta time, unscaled delta time을 적절하게 조합해서 사용하면 특수한 스킬로 적들은 멈춰있거나 느려졌는데 플레이어만 정상적인 속도로 움직이는 기능을 연출할 수 있습니다.

아웃트로

이번 영상에서는 Time 클래스의 time scale과 unscaled delta time 프로퍼티에 대해서 알아보았습니다.

이상 베르의 게임 개발 유튜브였습니다. 감사합니다.

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

- 유니티 에셋스토어 : https://prf.hn/click/camref:1100lkbzf/creativeref:1101l61541

 

[투네이션 후원] https://toon.at/donate/637735212761460238

반응형

안녕하세요! 여러분들과 함께 게임 개발을 공부하는 베르입니다!

이번에는 유니티 Time 클래스의 deltaTime 프로퍼티에 대해서 알아봅시다.

 

사용 엔진 버전 : 2020.3

 

타임라인

0:00 인트로

0:09 Time.deltaTime

2:58 아웃트로

 

스크립트

인트로

안녕하세요. 여러분들과 함께 게임 개발을 공부하는 베르입니다.

이번 강좌에서는 Time 클래스의 delta Time 프로퍼티에 대해서 알아봅시다.

deltaTime

먼저 deltaTime에서 delta는 보통 값의 차이를 의미하는 단어입니다.

시간을 의미하는 Time과 조합해서 생각해보면 deltaTime은 차이가 나는 시간이라는 뜻으로 지난 프레임이 완료되는 데까지 걸린 시간 차이를 의미하며 단위는 초 단위입니다.

한마디로 한 프레임을 진행하는데 걸린 시간이라는 뜻이죠.

그래서 게임을 진행하다가 컴퓨터 사양이나 게임의 최적화 문제로 게임의 프레임이 떨어지는 프레임 드랍 현상이 일어나면 이 deltaTime 값은 한 프레임의 화면을 렌더링하는데 걸리는 시간만큼 커지게 됩니다.

보통 30프레임 기준의 게임에서는 한 프레임당 deltaTime이 0.033정도가 나와야하고 60프레임 기준의 게임에서는 한 프레임당 0.016 정도가 나와야 합니다.

유니티 에디터에서 스크립트를 하나 생성하고 Start 함수에서 Application.targetFrameRate를 30으로 지정한 다음 Update 함수에서 Time.deltaTime을 디버그로 출력시키도록 코드를 작성합니다.

코드를 모두 작성한 다음에는 코드를 저장하고 에디터로 돌아가서 아무 게임 오브젝트에나 방금 만든 컴포넌트를 붙이고 게임을 실행해보면 앞에서 말한대로 약 0.033초에 가까운 값이 매 프레임마다 갱신되는 것을 볼 수 있습니다.

그리고 다시 스크립트에서 targetFrameRate를 60으로 변경하고 에디터로 돌아가서 테스트해보면 0.016초에 가깝게 deltaTime 값이 나오는 것을 확인할 수 있습니다.

그럼 이 delta time은 어디에 사용될까요?

그 예시를 보여드리도록 하겠습니다.

먼저 Update 함수에서 W키를 누르면 오브젝트를 이동시키는 코드를 작성해보겠습니다.

이 때 이동 코드에서 캐릭터의 이동 방향과 속도만 이용해서 캐릭터를 이동시키면 문제가 발생하게됩니다.

이 비교 영상처럼 프레임이 10일 때와 60일 때 캐릭터가 다른 속도로 움직이게 되는 겁니다.

이 문제의 원인은 프레임이 10일 때는 1초에 캐릭터를 10번 움직이게 되고, 프레임이 60일 때는 1초에 캐릭터를 60번 움직이기 때문입니다.

좀 더 풀어서 설명해보자면 이 코드에서는 프레임이 10일 때는 1의 속도로 캐릭터를 1초동안 10번 움직이기 때문에 이동한 거리가 10이 되는 것이고, 프레임이 60일 때는 1의 속도로 캐릭터를 1초동안 60번 움직이기 때문에 이동한 거리가 60이 됩니다.

1초 동안 움직인 횟수가 달라서 움직인 거리 역시 달라지는 것이죠.

이것은 컴퓨터의 성능이 오브젝트의 속도에 영향을 미치게 되는 것으로 보통의 게임에서는 발생해서는 안되는 문제입니다.

이 문제를 해결하기 위한 방법이 바로 이 이동 값에 delta time을 곱해주는 겁니다.

이렇게 이동 벡터에 delta time을 곱해주고 나면, 게임이 몇 프레임으로 진행되는지에 전혀 상관없이 오브젝트는 동일한 속도로 움직이게 됩니다.

이런 식으로 이동이나 회전 등 움직임에 있어서 시간의 영향을 받는 기능을 만들 때는 값에 deltaTime을 곱해서 흘러간 프레임 시간만큼만 가중치를 줌으로써 프로세서 속도의 영향에서 자유로워 지게됩니다.

아웃트로

이번 영상에서는 유니티 Time 클래스의 deltaTime에 대해서 알아보았습니다.

이상 베르의 게임 개발 유튜브였습니다. 감사합니다.

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

- 유니티 에셋스토어 : https://prf.hn/click/camref:1100lkbzf/creativeref:1101l61541

 

[투네이션 후원] https://toon.at/donate/637735212761460238

반응형

 

사용 버전 : 2019.4

스크립트

인트로

안녕하세요. 여러분들과 함께 게임 개발을 공부하는 베르입니다.

이번 영상에서는 유니티의 인보크에 대해서 알아보도록 하겠습니다.

기본 인보크

우선 인보크란 유니티 엔진에서 모든 유니티 스크립트의 기본 클래스인 MonoBehaviour 클래스에서 제공되는 함수로써 기본적으로 원하는 함수를 일정 시간 후에 호출하거나 일정 시간마다 반복해서 호출할 수 있게 해주는 기능을 제공합니다.

우선 인보크 기능을 테스트해보기 위해서 프로젝트 뷰에서 InvokeTester라는 이름으로 C# 스크립트를 생성하고 스크립트 에디터를 엽니다.

스크립트 에디터가 열리고 나면 CreateCube 함수를 만들고 큐브를 랜덤한 위치에 생성하도록 코드를 작성합니다.

그리고 Start 함수로 가서 Invoke 함수를 호출해줍니다.

이 때 Invoke로 호출될 함수의 이름을 문자열로 넣고 얼마나 시간이 흐른 뒤에 호출될 지를 매개변수로 넣어주면 됩니다.

지금은 3초로 설정하겠습니다.

코드를 저장하고 에디터로 돌아갑니다.

에디터로 돌아온 다음에는 씬에 빈 게임오브젝트를 하나 생성하고 거기에 InvokeTester 컴포넌트를 붙여줍니다.

그 다음 게임을 플레이시켜보면 3초 뒤에 큐브가 스폰되는 모습을 볼 수 있습니다.

이것이 가장 기초적인 인보크 사용 방법입니다.

반복 호출되는 인보크

그 다음 알아볼 것은 반복 호출되는 인보크입니다.

다시 스크립트 에디터로 돌아갑니다.

방금 배운 것처럼 매개변수에 호출할 함수의 이름과 시간만 넣으면 함수가 일정 시간 후에 한 번 호출됩니다.

여기에 Invoke 함수 대신에 InvokeRepeating 함수로 바꾸고 세 번째 매개변수에 1을 넣어줍니다.

이렇게 하면 InvokeRepeating이 호출되고 3초 후에 CreateCube 함수가 호출되며 그 뒤로 1초마다 계속해서 반복 호출됩니다.

코드를 저장하고 에디터로 돌아가서 게임을 실행해보겠습니다.

그러면 3초가 지난 후에 1초마다 계속 새로운 큐브가 생성되는 모습을 볼 수 있습니다.

인보크 멈추기

그 다음에는 동작 중인 인보크를 멈추는 방법을 알아보겠습니다.

다시 스크립트도 돌아갑니다.

인보크를 멈추기 위해서는 CancelInvoke 함수를 사용하면 됩니다.

이 때 매개변수에 아무것도 넣지 않으면 이 게임오브젝트에서 동작하고 있는 모든 인보크들을 멈추게하고 매개변수에 함수 이름을 넣으면 그 함수 이름으로 실행된 인보크들만 멈추게 할 수 있습니다.

그럼 인보크가 멈추는 것을 확인해보기 위해서 코드를 작성하겠습니다.

먼저 CreateCube 함수를 복사해서 큐브 대신 구체를 만들어내는 CreateSphere 함수를 만들어줍니다.

그리고 업데이트 함수에서 키보드 숫자 1을 누르면 CreateCube 함수가 InvokeRepeating 되게 만들어 주고 2를 누르면 CreateSphere 함수가 InvokeRepeating 되게 만들어줍니다.

그리고 숫자 3을 누르면 CreateCube 함수가 CancelInvoke 되고 4를 누르면 CreateSphere 함수가 CancelInvoke 되게 해줍니다.

마지막으로 ESC를 누르면 동작 중인 모든 인보크가 멈추게 만듭니다.

코드를 저장하고 에디터로 돌아가서 게임을 실행합니다.

그리고 1과 2를 누르면 큐브와 구체가 계속해서 생성되는 모습을 볼 수 있습니다.

이 상태에서 3을 누르면 큐브의 생성이 멈추고 4를 누르면 구체의 생성이 멈춥니다.

다시 1과 2를 눌러 큐브와 구체를 생성되게 만든 다음 ESC 키를 누르면 큐브와 구체의 생성이 동시에 멈추는 것을 볼 수 있습니다.

인보크 상태 확인하기

이번에는 인보크가 동작 중인지 확인하는 방법을 알아보겠습니다.

인보크가 동작 중인지 확인하기 위해서는 IsInvoking 함수를 사용하면 됩니다.

이 함수 역시 CancelInvoke 함수와 마찬가지로 매개변수로 함수 이름을 넣으면 그 함수에 대한 인보크가 동작 중인지 확인할 수 있고 매개변수를 사용하지 않으면 아무 인보크나 동작하고 있는지를 체크할 수 있습니다.

이번에는 숫자 5를 누르면 CreateCube 함수에 대한 인보크를 체크하고 6을 누르면 CreateSphere 함수에 대한 인보크를 체크해서 로그를 출력하도록 코드를 작성합니다.

그리고 숫자 7을 누르면 매개변수 없이 인보크를 체크하도록 만듭니다.

코드를 모두 작성한 다음에는 저장하고 에디터로 돌아가서 게임을 실행합니다.

그리고 인보크를 실행하기 전에 5, 6, 7을 순서대로 눌러보면 어떠한 인보크도 동작하고 있지 않음을 로그로 확인할 수 있습니다.

그 다음에 1을 눌러 CreateCube 함수를 인보크로 동작시키고 5, 6, 7을 누르면 CreateCube 인보크 확인 로그와 모든 인보크 확인 로그를 통해서 인보크가 동작하고 있음을 확인할 수 있습니다.

그리고 2를 누르고 CreateSphere 함수까지 인보크로 동작시키고 5, 6, 7을 누르면 모든 인보크가 동작하고 있음을 로그로 확인할 수 있습니다.

이번에는 3을 눌러서 CreateCube 함수의 인보크를 중지시키고 5, 6, 7을 누르면 CreateCube 인보크가 동작하지 않는다는 로그를 볼 수 있습니다.

마지막으로 4를 눌러서 CreateSphere 함수의 인보크를 중지시키고 5, 6, 7을 누르면 모든 인보크가 동작하지 않는것을 로그로 확인할 수 있습니다.

멈추지 않는 인보크

추가로 유니티 엔진에서 게임오브젝트의 Update 함수과 코루틴 같은 기능은 게임오브젝트나 컴포넌트가 비활성화되면 동작을 멈추는 것을 알고 있으실 겁니다.

하지만 인보크 기능은 해당 게임오브젝트나 컴포넌트가 비활성화되어도 동작을 멈추지 않습니다.

인보크를 멈추기 위해서는 반드시 CancelInvoke 함수를 호출하거나 게임오브젝트 자체를 파괴해야 합니다.

하지만 코루틴

이렇게 인보크를 사용하면 원하는 함수를 일정 시간이 지난 후에 호출하거나 원하는 시간 간격으로 호출할 수 있는데 이 기능은 코루틴을 사용해서도 똑같이 구현할 수 있습니다.

그리고 유니티 공식 문서를 보면 성능 향상과 유지보수를 위해서는 코루틴을 사용할 것을 권장하고 있습니다.

우선 성능적인 측면을 보자면 인보크는 함수를 문자열로 된 이름으로 찾아서 사용하고 있습니다.

이렇게 문자열 함수 이름으로 함수를 찾아서 사용하기 위해서는 C#의 리플렉션이라는 기능을 사용하게 되는데 이렇게 문자열 함수 이름으로 리플렉션을 통해서 함수를 동작시키는 과정은 직접 함수를 호출하는 것에 비해서 수 천 배 정도 느리다고 합니다.

물론 컴퓨터의 사양이 많이 상승한 최근에는 유의미한 성능 저하는 당장 일어나지 않겠지만 인보크를 남용하면서 게임을 만들다보면 게임의 사양이 많이 올라갔을 때 최적화를 위해서 인보크를 사용하는 코드를 대부분 갈아엎어야 할 수도 있습니다.

아웃트로

이번 영상에서는 유니티 엔진에서 원하는 함수를 일정 시간이 지난 후에 호출하거나 원하는 시간 간격으로 호출할 수 있게 만들어주는 인보크에 대해서 알아보았습니다.

이상 베르의 게임 개발 유튜브였습니다. 감사합니다.

타임라인

0:00 인트로

0:09 기본 인보크

1:12 반복 호출되는 인보크

1:55 인보크 멈추기

3:22 인보크 상태 확인 하기

4:51 멈추지 않는 인보크

5:14 하지만 코루틴

6:06 아웃트로

 

반응형

 

유니티 2020 버전 이전에서 제네릭 인수를 사용하는 유니티 이벤트의 복잡한 직렬화 방식이 유니티 2020버전에서 변경되었습니다. 이부분에 대해서 알아봅시다.

 

타임라인

0:00 2020 이전 버전의 유니티 이벤트 Generic Serialization

1:11 유니티 2020에서 바뀐 유니티 이벤트 Generic Serialization

반응형

 

유니티 이벤트와 유니티 액션을 사용을 사용하는 방법을 알아봅시다.

 

타임라인

0:00 유니티 이벤트와 유니티 액션 개요

1:15 유니티 이벤트의 예시(버튼 UI 컴포넌트)

1:49 유니티 이벤트를 사용해서 스크립트에서 원하는 이벤트 구현하기

2:48 유니티 이벤트에 콜백 함수를 등록할 클래스 만들기

3:32 이벤트 기능 테스트

3:48 스크립트에서 콜백 함수 등록하기

4:51 유니티 이벤트에 매개변수 지정하기

5:24 유니티 이벤트의 매개변수 지정하기의 단점과 해결방법

5:50 유니티 액션

반응형

 

게임에서 사용되는 FPS(Frame Per Second)란 무엇인지 알아보고, 유니티 엔진에서 FPS를 측정하는 방법과 게임의 목표 FPS를 설정하는 방법을 알아봅시다.

 

타임라인

0:03 FPS 개요

3:29 에디터에서 게임 뷰의 FPS 보기

4:11 FPS 출력 기능 구현하기

5:44 FPS 출력 기능 테스트

6:31 게임의 목표 프레임 설정하기

반응형

+ Recent posts