코루틴(Coroutine)의 개념과 동작 원리

2024. 11. 13. 14:10·유니티(Unity)/이론 정리

 

Unity에서 사용하는 코루틴(Coroutine)은 코드의 흐름을 제어할 수 있도록 해주는 기능입니다. 코루틴을 사용하면 특정 이벤트가 발생하거나 시간이 경과한 뒤에 실행될 작업을 손쉽게 처리할 수 있습니다. 오늘은 이 코루틴에 대한 개념과 원리에 대해 자세히 알아보도록 하겠습니다.

 


코루틴(Coroutine)이란?

 

함수를 호출하면 시작과 끝이 1 프레임 안에 수행됩니다. 하지만 게임을 개발하다 보면 특정 로직이 몇 프레임(혹은 몇 초) 동안 수행되어야 하는 순간들이 많습니다. 그래서 코루틴이라는 새로운 개념이 나타나게 되었습니다.

 

코루틴: 특정 작업(Task)를 다수의 프레임으로 분산시킬 수 있는 실행 기능

"Coroutine"은 "Co"와 "Routine"이 합쳐진 말로, 루틴(함수)들이 서로 협력하면서 실행된다는 의미를 가집니다. 즉, 함수들 간의 흐름을 조정하며 작업을 수행합니다.

 

 

 


코루틴 사용 방법

 

    void Start()
    {
        // Test 코루틴 실행
        StartCoroutine(nameof(Test));
        
        // Test 코루틴 종료
        StopCoroutine(nameof(Test));
        
        // (TempManager가 호출한) 모든 코루틴 종료 
        StopAllCoroutines();
    }
    
    IEnumerator Test()
    {
        // 1초 후 아래 로직 수행
        yield return new WaitForSeconds(1f);
        
        // 1초 후 아래 로직 수행 (Time.deltaTime 영향을 받지 않음)
        yield return new WaitForSecondsRealtime(1f);  

        // 다음 FixedUpdate 호출 까지 대기 후 실행
        yield return new WaitForFixedUpdate();
        
        // 모든 렌더링 작업이 완료되어 프레임이 끝날 때까지 대기 후 실행
        yield return new WaitForEndOfFrame();  
        
        // 1프레임 후 아래 로직 수행
        yield return null;
        
        // 아래 구문이 수행되지 않고 빠져 나옴
        yield break;
        
        // {condition}이 참일 때까지 대기 후 실행
        yield return new WaitUntil(() => condition);
        
        // {isProcessing}이 거짓이 될 때까지 대기 후 실행
        yield return new WaitWhile(() => isProccessing);
        
        Debug.Log("End");
    }

 

 

코루틴 실행 및 중단 방법은 다음과 같다.

  • StartCoroutine(string name): {name} 코루틴 실행
  • StopCoroutine(string name): 소유권이 Call인 {name} 코루틴 중단 
  • StopAllCoroutines(): 소유권이 Call인 모든 코루틴 중단
코루틴마다 소유권이 존재하며, Caller가 대상입니다.

 

 

코루틴 함수 작성 방법은 다음과 같습니다.

  • 반환자로 Ienumerator을 선언합니다.
  • yield return 구문을 통해 함수 실행 조건을 추가합니다.
  • yield break 구문을 통해 함수를 중단합니다.

 

 

 


코루틴 작동 원리

 

Unity의 코루틴은 IEnumerator와 MoveNext() 함수를 통해 프레임 단위로 실행됩니다. 테스트로 IEnumerator 인터페이스를 통해 MoveNext() 함수를 직접 찍어보도록 하겠습니다.

 

    void Start()
    {
        IEnumerator IEnum = Test();
        while (IEnum.MoveNext()) 
        {
            object result = IEnum.Current;
            Debug.Log("Result: " + result);
        }
    }
    
    IEnumerator Test()
    {
        Debug.Log("시작");
        yield return new WaitForSeconds(1f);
        Debug.Log("1");
        yield return new WaitForSeconds(1f);
        Debug.Log("2");
        yield return new WaitForSeconds(1f);
        Debug.Log("3");
    }

 

단순히 호출 형태로 구현하면 위와 같습니다. 하지만 위 방식으로는 1초 마다 수행되지 않습니다. 그래서 코루틴을 처리하기 위해선 Monobehaviour 클래스 내부의 StartCoroutine 함수를 호출해야 합니다.

StartCoroutine을 호출하면 Unity 엔진 내부 C++ 코드가 동작하는데, 여기서 코드를 제어하는 로직이 수행됩니다.

 

 

 

IEnumerator coroutine = Test();

while (coroutine.MoveNext())
{
    object current = coroutine.Current;
    if (current is WaitForSeconds wait)
    {
        Debug.Log($"Wait for {wait.Seconds} seconds");
    }
}

 

Unity 엔진의 네이티브 C++은 비공개라 정확한 확인은 어렵지만, 아마도 위처럼 MoveNext() 함수를 수행할 때마다 현재 YieldInstruction에 따라 코드를 제어하는 것으로 보입니다. 이를 통해 개발자는 코루틴을 통해 원하는 순간에 로직을 처리할 수 있습니다.

YieldInstruction: 코루틴의 중단 및 행동을 제어하기 위해 사용되는 Base 클래스입니다. WaitForSeconds나 WaitForEndOfFrame 같은 클래스들이 이 클래스를 상속받습니다.

 

 

 

💡  코루틴은 진정한 비동기 처리가 아닙니다!

 

코루틴은 프레임 단위로 오직 메인 스레드 위에서 작업의 실행을 분할하여 로직을 처리합니다. 단순히 프레임 단위로 작업을 수행하는 조건을 체크하며 기다릴 뿐입니다. 따라서 코루틴은 작업 도중 발생하는 I/O 작업을 처리하는 비동기(asynchronous) 처리로 간주되진 않습니다.

 

 

 


정리

코루틴은 Unity에서 비동기 처리를 구현할 때 유용합니다. 코루틴은 특정 작업을 한 프레임이 아닌, 여러 프레임으로 분산하여 처리합니다. 코루틴을 제대로 사용하기 위해선 MoveNext 동작 원리를 이해하고, YieldInstruction을 통해 프레임을 분산하여 시스템을 설계할 필요가 있습니다.

 

 

추천글

 

https://docs.unity3d.com/kr/2022.3/Manual/Coroutines.html

 

코루틴 - Unity 매뉴얼

코루틴을 사용하면 작업을 다수의 프레임에 분산할 수 있습니다. Unity에서 코루틴은 실행을 일시 정지하고 제어를 Unity에 반환하지만 중단한 부분에서 다음 프레임을 계속할 수 있는 메서드입니

docs.unity3d.com

 

https://medium.com/supercent-blog/%EC%9C%A0%EB%8B%88%ED%8B%B0-%EA%B8%B0%EB%B3%B8%EA%B8%B0-%EC%BD%94%EB%A3%A8%ED%8B%B4-coroutine-5048334a2e2f

 

유니티 기본기 : 코루틴(Coroutine)

유니티의 기본! 코루틴(Coroutine)의 개념과 활용, 그리고 자주하는 실수의 원인을 파악해봐요

medium.com

 

'유니티(Unity) > 이론 정리' 카테고리의 다른 글

[Unity] .NET이란?  (4) 2024.11.17
Unitask의 개념과 사용법  (0) 2024.11.14
[Unity Korea] 객체 지향 설계 원칙 (SOLID)  (0) 2024.11.12
클래스 이름 짓기 [ 2편 ] + MVC 패턴  (2) 2024.11.11
클래스 이름 짓기 [ 1편 ]  (1) 2024.11.10
'유니티(Unity)/이론 정리' 카테고리의 다른 글
  • [Unity] .NET이란?
  • Unitask의 개념과 사용법
  • [Unity Korea] 객체 지향 설계 원칙 (SOLID)
  • 클래스 이름 짓기 [ 2편 ] + MVC 패턴
게임을 제작하는 사람
게임을 제작하는 사람
안녕하세요, 게임 개발자 천냥입니다! 게임을 제작하는 개발자들에게 도움이 될만한 정보와 지식을 제공하는 블로그입니다 ;)
  • 게임을 제작하는 사람
    천냥의 게임 개발 일지
    게임을 제작하는 사람
  • 전체
    오늘
    어제
    • 분류 전체보기 (87)
      • 유니티(Unity) (56)
        • 콘텐츠 개발 (7)
        • 툴 개발 (7)
        • 이슈 도감 (10)
        • 최적화 기법 (4)
        • 쉐이더 (3)
        • 포톤 (0)
        • 이론 정리 (15)
        • 유용한 패키지 정리 (3)
        • 패키지: Cinemachine 정리 (7)
      • C# (2)
      • IT (29)
        • 기술 정리 (2)
        • 알고리즘 (26)
        • Git (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    C++
    끝 없는 2d 맵
    쉐이더
    커스텀 패키지
    클래스 이름
    티스토리챌린지
    코딩 테스트
    카메라
    allin1spriteshader
    시네머신
    openupm
    Unity
    Cinemachine
    URP
    UI
    Shader
    upm 개발
    유니티
    addressable
    editor
    클래스 명명
    무한 플랫포머
    오블완
    에디터
    sprite atlas
    코테
    2d endless platform 구현
    custom package
    최적화
    패키지 버전 관리
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
게임을 제작하는 사람
코루틴(Coroutine)의 개념과 동작 원리
상단으로

티스토리툴바