유니티에서 코루틴을 사용할 때 함수 이름의 문자열 또는 IEnumerator
를 반환하는 함수를 사용해서 호출할텐데, 이 때 사용되는 yield
가 무엇인지 더 자세히 알아보기 위해 공부 및 글을 남깁니다. 😄
코루틴?
💡 Quotation
반복기에서 yield 문을 사용하여 다음 값을 제공하거나 반복 종료를 알립니다. - MSDN
유니티에서 코루틴을 스레드 대신 사용한다고 하여 내부적으로 thread-safe 를 준수하는 스레드? 인 줄 알았으나, 단순히 싱글 스레드에서 반복문을 돌려 처리하는 것이었습니다.
그럼 어떻게 싱글 스레드에서 스레드를 사용하는 것 처럼 쓰일 수 있을까요? 아니 그 전에 스레드를 왜 사용했을까요?
스레드 왜 사용했을까?
😭 코루틴에
Thread.Sleep(1000);
을 실행하면 메인 스레드가 멈춥니다.
위 극단적인 예와 같이 메인 스레드에서 어떤 작업을 처리할 때 블록이 걸리기 때문에 사용했습니다. 어떻게 1초 후에 실행해야 하는 작업을 메인 스레드의 중단 없이 처리할까요?
yield 키워드
사실 싱글 스레드에서 1초가 걸리는 작업을 블록 없이 수행하는 방법은 사실 없습니다. 하지만 yield
키워드를 사용해서 1초의 작업을 작게 나누어서 한 프레임을 처리하는데 걸리는 시간보다 작게 나눌수는 있습니다! 😎
⚠️ 매우 극단적인 예시
1초를 10번 나누어 10FPS 가 되도록!
|
|
1초 짜리 작업을 한번에 수행한다면 1초 동안 블록이 발생하겠죠? 하지만 위 코드처럼 yield
키워드를 사용해서 작업 시간을 0.1초 씩 나눈다면 블록이 걸리긴 하겠지만 덜 할겁니다. 100번으로 나눈다면 한 프레임당 10ms, 100FPS 가 나오고 블록이 발생하지 않는 것 처럼 보이기도 하겠네요!
동작
💡
yield
키워드를 만나면 함수를 호출한 반복기로 돌아갑니다.
|
|
간단한 C# 예제이고, Test()
라는 함수를 StartCoroutine()
으로 실행했다고 가정했을 때 위 결과는 아래의 이미지와 같습니다!
코루틴 작업 0 실행 후 호출한 곳으로 돌아가서 작업을 처리하고 있습니다.
유니티는 호출한 곳으로 돌아가 한 프레임을 처리한 후 다시 코루틴의 작업으로 들어가서 작업을 진행합니다. 이 때 코루틴 작업 1이 진행 되겠죠.
정리
- 코루틴 함수에서
yield
를 만나기 전 까지 작업 yield
를 만나면 호출한 곳으로 복귀 및 한 프레임 처리- 코루틴 함수로 들어가서 다음
yield
를 만나기 전 까지 작업 - 반복…