과제 진행 과정에서 코루틴을 쓸 일이 많았다. 반복적인 작업을 수행하거나, UI 효과를 위해서 시간을 정지해야 할 때, 실행되어야 할 다른 내용들이 멈추면 안 되는 상황들이 있어서 사용하게 되었다.
이전에도 코루틴을 써본 적이 있지만, 자세히 파고 들어 어떻게 작동하며 어떤 구조를 가지고 있고, 어떤 점을 주의해야 하는지 명확하게 이해하지는 못해서 공부할 필요성을 느꼈다.
코루틴 (Coroutine)
코루틴은 Unity에서 제공하는 특수한 프로그래밍 구조로,일반 메서드와는 다르게 실행을 일시 중지하고 나중에 다시 재개할 수 있다. 코루틴은 IEnumerator 타입의 메서드를 통해 구현되며, 코루틴은 yield를 사용하여 이러한 중지와 재개를 한다. 주로 비동기적인 동작이나 지연된 작업을 수행할 때 유용하다.
1. 일시 중단 및 재개:
코루틴은 yield return 문을 사용하여 실행을 일시적으로 중단하고, 나중에 해당 위치에서 재개할 수 있다.
2. 메인 스레드에서 실행:
Unity의 코루틴은 메인스레드에서 실행된다. 이는 병렬 처리를 의미하는 것이 아닌, 프레임 간의 작업 분배를 가능하게 한다.
3. 다양한 yield 옵션:
Unity에서는 다양한 yield 옵션을 제공하여, 특정한 시간 후, 특정 조건이 충족될 때, 다른 코루틴이 완료될 때 등 다양한 시나리오에 따라 코루틴의 재개를 제어할 수 있다.
비동기적 (지연된) 작업
코루틴의 '비동기적' 작업은 실제로 병렬로 실행되는 것이 아니라, 일련의 작업을 순차적으로 처리하지 않고, 특정 작업을 일시 중단하고 다른 작업을 수행한 후 원래 작업으로 돌아올 수 있다는 것을 의미한다.
예시)
IEnumerator DialogueSequence()
{
StartTalking("Hello there!");
yield return new WaitForSeconds(2); // 2초 동안 대기
StartTalking("How are you today?");
}
- 여기서 yield return new WaitForSeconds(2);는 코루틴의 실행을 2초 동안 중단한다. 이 기간 동안 메인 스레드는 다른 작업(예: 게임 로직, 렌더링 등)을 계속 수행할 수 있다.
- 또한, 웹에서 데이터를 가져오는 경우와 같이 외부 리소스에 액세스해야 할 때 코루틴을 사용하여 응답을 기다릴 수 있다. 이는 작업을 "지연"한다는 것을 의미한다.
* 코루틴과 timeScale의 연관성:
- WaitForSeconds: 이 yield 명령은 Time.timeScale에 영향을 받는다. 즉, timeScale이 0이면 WaitForSecodns를 사용하는 코루틴은 일시 중단 상태로 유진된다. timeScale이 0.5이면 WaitForSeconds의 대기 시간이 2배로 늘어난다.
- WaitForFixedUpdate: 이 yield 명령은 FixedUpdate()의 호출에 기반한다. 즉, timeScale의 영향을 받는다.
- WaitForEndOfFrame: 이 yield 명령은 렌더링 프레임의 마지막에 발생하므로 Time.timeScale의 영향을 받지 않는다.
게임 루프와 렌더링 파이프라인
Unity에서는 각 프레임마다 여러 단계를 거치는데, 이를 게임 루프라고 한다. 게임 루프의 대략적인 단계는 다음과 같다:
1. `Update`: 게임 로직 업데이트 (모든 `Update()` 함수가 여기에서 호출됩니다).
2. `LateUpdate`: `Update` 후 처리 (모든 `LateUpdate()` 함수가 여기에서 호출됩니다).
3. 렌더링: 실제 그래픽을 계산하고 화면에 그리는 작업이 이루어집니다. 여기에는 여러 단계가 있습니다 (예: 셰이딩, 라이팅 계산, 포스트 프로세싱 등).
4. `WaitForEndOfFrame`: 렌더링 작업이 끝난 직후 발생합니다.
Time.timeScale
`Time.timeScale`은 Unity의 시간을 조절하는 변수이다. 주로 게임의 진행 속도를 제어할 때 사용된다. `Time.timeScale` 값이 `0`이면 `Update`와 `FixedUpdate` 함수는 호출되지 않는다. 그러나 렌더링 파이프라인 자체는 계속 작동한다.
`WaitForEndOfFrame`는 렌더링 작업이 모두 완료된 후에 코루틴의 실행을 재개하도록 한다. 이 `yield` 명령은 렌더링 파이프라인의 마지막 단계에서 발생하므로, `Time.timeScale`의 영향을 받지 않는다. 다시 말해, 실제로 화면에 그려지는 그래픽 연산이 끝난 직후에 작동하게 된다.
알아보다 보니 버그가 발생한 이유가 코루틴 뿐만 아니라 TimeScale과도 연관성이 있을 것 같다. 내일은 TimeScale에 대해 공부해봐야겠다.
'👾 내일배움캠프 > 🎮 TIL & WIL' 카테고리의 다른 글
내일배움캠프 6주차 WIL - 팀 프로젝트 회고 (0) | 2023.09.21 |
---|---|
내일배움캠프 29일차 TIL - GameManager (0) | 2023.09.21 |
내일배움캠프 26일차 TIL - Json을 활용한 데이터 저장 (0) | 2023.09.21 |
내일배움캠프 25일차 TIL - Scriptable Object (1) | 2023.09.21 |
내일배움캠프 5주차 WIL - 유니티 기초 다지기 (0) | 2023.09.21 |