Notice
Recent Posts
Recent Comments
Link
«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
Tags
more
Archives
Today
Total
관리 메뉴

뭐라도 쓰겠지

25.04.19 / 코루틴(Coroutine) 본문

프로그래밍/게임 개발

25.04.19 / 코루틴(Coroutine)

김데피 2025. 4. 19. 21:55

유니티에서 코루틴(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 객체를 이용해 다양한 시점에 함수를 재개할 수 있다.

 

다만, 멀티스레딩이 아니라는 점을 유의해야 하며, 무거운 연산을 코루틴으로 분산시키더라도 결국 메인 스레드에서 수행되므로 게임 성능에 영향을 줄 수 있다.