뭐라도 쓰겠지
25.04.19 / 코루틴(Coroutine) 본문
유니티에서 코루틴(Coroutine)은 여러 프레임(Frame)에 걸쳐 함수를 중단했다가 재개하는 개념이다. 정확히 말하자면 C#의 IEnumerator 인터페이스와 yield 키워드를 활용해 구현된 '반복자(Iterator) 함수'를 유니티 엔진에서 특정 시점마다(매 프레임, 특정 시간 후 등) 다시 호출하여 마치 함수 실행이 멈췄다가 이어지는 것처럼 보여주도록 만든 구조이다.
어떻게 동작하는가?
1. 코루틴 함수 정의
- IEnumerator를 반환하는 함수 안에서 yield return 문을 사용해 함수 실행을 일시 중지 할 수 있다.
- 유니티는 MonoBehaviour.StartCoroutine()로 이 코루틴 함수(반복자)를 실행시킨다.
2. 코루틴 실행 흐름
- 코루틴 함수가 시작되면, yield return 문을 만나기 전까지는 일반 함수와 동일하게 실행된다.
- yield return 문을 만나면 함수를 빠져나오고, 그 다음 단계는 유니티의 메인 루프가 조건에 맞춰 다시 실행한다.
- 이 과정을 반복하다가 함수가 끝까지 실행되거나 yield break를 만나면 해당 코루틴이 종료된다.
3. "스레드가 아니다"
- 유니티 코루틴은 메인 스레드에서 "나누어 호출"되는 것이지, 별도의 스레드로 병렬 실행되는 것이 아니다.
- 따라서 복잡한 연산을 코루틴에 넣는다고 해도, 다른 작업과 실제 병렬 실행되진 않는다.
예시 코드
using UnityEngine;
using System.Collections;
public class CoroutineExample : MonoBehaviour
{
void Start()
{
// 코루틴 실행
StartCoroutine(MyCoroutine());
}
IEnumerator MyCoroutine()
{
Debug.Log("코루틴 시작: 첫 부분 실행");
// 한 프레임 쉬고 다음 프레임에 재개
yield return null;
Debug.Log("코루틴 재개: 다음 프레임");
// 3초 기다린 뒤 재개
yield return new WaitForSeconds(3.0f);
Debug.Log("코루틴 재개: 3초 뒤");
// 새 코루틴을 실행하고, 그것이 끝날 때까지 대기
yield return StartCoroutine(OtherCoroutine());
Debug.Log("OtherCoroutine 완료 후 재개");
Debug.Log("코루틴 종료");
}
IEnumerator OtherCoroutine()
{
Debug.Log("OtherCoroutine 실행 중…");
yield return new WaitForSeconds(2.0f);
Debug.Log("OtherCoroutine 끝");
}
}
- yield return null : 다음 프레임까지 대기
- yield return new WaitForSeconds(3.0f) : 3초 대기
- yield return StartCoroutine(...) : 해당 코루틴이 완료될 때까지 대기
유용한 yield return 객체들
유니티에서는 YieldInstruction 및 CustomYieldInstruction 계열의 다양한 객체를 제공하거나 만들 수 있다. 대표적으로 다음과 같은 것들이 있다.
1. WaitForSeconds(float seconds)
- 지정된 seconds 초만큼 기다린 뒤 재개
2. WaitForEndOfFrame()
- 프레임 렌더링이 모두 끝난 뒤(End of Frame)에 재개
3. WaitForFixedUpdate()
- 물리 연산이 업데이트되는 시점(Fixed Update) 이후에 재개
4. WaitUntil(() => condition), WaitWhile(() => condition)
- 특정 조건이 참 / 거짓이 될 때까지 대기
5. 커스텀 YieldInstruction
- 사용자가 CustomYieldInstruction을 상속해서, 원하는 조건이 만족될 때까지 대기하는 로직 구현 가능
사용 예시
1. 애니메이션(연출) 순서 제어
- 한 이벤트 후에 잠시 텀을 두고(WaitForSeconds 등) 카메라 이동, 대사 출력 등 여러 액션을 코루틴 내부에서 순차적으로 호출 가능
2. 네트워크 호출 후 처리
- 비동기 요청 함수가 완료될 때까지 yield return www(과거 UnityWebRequest)로 대기 -> 이후 결과에 따라 로직 처리
3. 타임라인(씬 전환) 연출
- 일정 시간 간격으로 화면 전환, UI 표시/숨기기, 효과음 재생 등을 일렬로 관리
주의사항
1. 실제 멀티 스레딩이 아님
- 코루틴 내부에 무거운 계산 로직을 넣으면 프레임 드랍이 발생할 수 있음
- 꼭 병렬화가 필요한 로직은 별도의 Thread나 Task (비동기 C# 스레드)로 처리 후 결과를 메인 스레드에서 받아와야 함
2. 코루틴 중도 정지
- StopCoroutine(코루틴)을 통해 코루틴을 중간에 종료시킬 수 있으며, StopAllCoroutines()를 사용하면 그 메소드를 호출한 MonoBehaviour 인스턴스에서 실행중인 모든 코루틴이 중지된다. 즉 해당 스크립트에서 StartCoroutine으로 시작된 모든 코루틴을 멈춘다는 뜻이지, 동일 게임 오브젝트의 다른 스크립트에서 시작된 코루틴, 다른 게임 오브젝트에서 시작된 코루틴까지 모두 멈추는 것은 아니다.
3. Lifecycle
- 씬 전환이나 GameObject가 비활성화될 때(MonoBehaviour가 Destroy될 때 등), 코루틴도 함께 사라질 수 있다.
정리하자면 유니티 코루틴은 IEnumerator를 사용해 함수를 일시 중단했다가(yield), 특정 조건이 충족되면 다시 실행을 반복하며, 여러 프레임에 걸쳐 순차 로직을 쉽게 구현할 수 있도록 만든 기능이다.
주로 시간 지연이나 순차 이벤트 처리에 매우 유용하고 여러 yield return 객체를 이용해 다양한 시점에 함수를 재개할 수 있다.
다만, 멀티스레딩이 아니라는 점을 유의해야 하며, 무거운 연산을 코루틴으로 분산시키더라도 결국 메인 스레드에서 수행되므로 게임 성능에 영향을 줄 수 있다.
'프로그래밍 > 게임 개발' 카테고리의 다른 글
25.04.19 / 텍스처 이미지가 2의 제곱수 사이즈인 이유 (0) | 2025.04.19 |
---|---|
25.04.19 / UV 좌표계(UV Coordinate System), 텍스처 매핑(Texture Mapping) (0) | 2025.04.19 |
25.04.19 / 디퍼드 렌더링(Deferred Rendering) (0) | 2025.04.19 |
25.04.18 / Volumetric Light, Volumetric Shadow (0) | 2025.04.18 |
25.04.18 / 글로벌 일루미네이션(Global Illumination, GI) (0) | 2025.04.18 |