본문 바로가기
Engine/Unity

Unity Coroutine

by 뇌 속의 통 2025. 2. 20.

작업을 하다보면 가끔씩 함수를 쓸때 바로 실행되는 것이 아니라 일정 시간 뒤에 동작을 하게끔 구현하고 싶을때가 있다.

 

예를 들어 게임이 시작되면 Ready라는 글자가 나오고 5초 뒤 Start라는 글자가 나온 뒤 게임이 시작하는 방법을 생각해보자.

 

 

    bool isGameStart;
    float startTime = 5.0f;
    float startTimer;


    void Update()
    {
        startTimer += Time.deltaTime;

        if (startTime < startTimer)
        {
            isGameStart = true;
        }    
    }

 

위와 같이 설정하면 5초뒤 isGameStart변수가 true가 되며 그에 맞는 로직을 실행하게 될 것이다.

그러나 위 코드에는 여러 문제점이 있다.

 

매번 Update 문을 통해 확인하므로 호출이 너무 불필요하게 잦고, startTimer 초기화를 해주지 않아 isGameStart = true가 5초 뒤부터 게임이 끝날때까지 계속 호출 된다.

 

이외에도 다양한 문제가 발생할 수 있는 코드가 된다.

 

코드를 진행하다가 잠시 멈추고 싶을때. 위의 예시와 같이 5.0초 뒤에 다른 동작을 하게끔 하고 싶을때

이럴때 사용하는 것이 바로 유니티의 코루틴이다.

 

쉽게 생각하면 함수를 진행하다가 잠시 해당 함수를 멈추고 싶을때 사용하는 것이다.

 

코루틴 사용하기

코루틴을 사용하는 방법은 아주 간단하다.

우선 내가 진행하다가 멈추게끔 하고 싶은 함수를 생각해본다.

 

그 다음 그 함수를 구현할때 반환형식을 IEnumerator로 설정한다. 그리고 코드 안에  yield return을 넣는다.

 

    IEnumerator TestFunction() 
    {

        LoadReadyImage();

        yield return new WaitForSecondsRealtime(5.0f);

        UnloadReadyImage();
        GameStart();
    }

 

IEnumerator는 다음에 설명하기로 하고 우선 위와 같이 코드를 작성해보자.

위의 코드는 다음과 같이 진행된다. 이 함수가 호출되면 가장 첫번째 줄의 LoadReadyImage() 함수를 통해 ReadyImage가 화면에 나타난다.

 

그다음 yield return을 만나면 제어권을 유니티에게 주게 된다.

쉽게 생각하면 함수를 멈추고 다른 동작들을 하게 된다.

 

그리고 우리가 설정한 return값이 흐르고 나면 다시 아래 코드를 동작하면서  ReadyImage를 화면에서 지우고, 게임이 시작된다.

 

Ready 이미지 화면에 띄움 -> 실제 시간으로 5.0초 기다림 -> Ready 이미지를 화면에서 지움 -> 게임이 시작됨.

 

yield return을 통해 우리는 시간을 줄 수 있는데 각각 다음과 같다.

WaitForSeconds(N); 게임 시간 기준 N초 대기
WaitForSecondsRealtime(N); 실제 시간 기준 N초 대기
WaitForEndOfFrame(); 모든 렌더링이 끝날 때까지 대기
WaitForFixedUpdate(); 다음 FixedUpdate가 호출될 때까지 대기
WaitUntil(condition); condition(== 특정조건)이 true가 될 때까지 대기
WaitWhile(condition); condition(== 특정조긴)이 false가 될 때까지 대
StartCoroutine(Function); Function(코루틴 함수)가 끝날 때까지 대기
null; 다음 프레임까지 대기
AsyncOperation; 비동기 작업이 끝날 떄까지 대기
break; 코루틴 중단

 

 

몇가지 좀 더 보자면,

 

시간을 기다려야 한다면 : WaitForSeconds, WaitForSecondsRealtime

특정 시점까지 기다려야 한다면 : WaitForEndOfFream, WaitForFixedUpdate

조건이 충족되길 기다려야 한다면 : WaitUntill, Wait While

다른 코루틴을 기다려야 한다면 : StartCoroutine

프레임에 한번씩은 호출해야 한다면 : null

로딩을 대기해야 한다면 : AsyncOperation

 

마지막으로 코루틴을 사용할때에는 StartCoroutine()안에 해당 함수를 넣으면 되고, 해당 코루틴을 멈추고 싶다면 StopAllCoroutine(모든 코루틴 종료), StopCoroutine(멈출 코루틴)으로 특정 코루틴을 멈추면 된다.

 

StartCoroutine 반환값이 Coroutine이므로 해당 객체를 받아서 StopCoroutine의 객체로 넣어주면 됨.

 

 

* Unity의 프레임 처리 순서

 

  • Input 처리: 사용자 입력 처리
  • FixedUpdate : 물리 연산
  • Update: 일반적인 게임
  • LateUpdate: 오브젝트 간 위치, 상태 조정
  • 렌더링 준비: 카메라와 오브젝트 정보 준비
  • 렌더링: GPU에서 화면에 그리기
  • End of Frame: 렌더링 작업 완료 (이때 후처리 가능)

 

문제 1. 

코루틴을 사용하여 2초 간격으로 3번 Hello World 출력하기.

 

정답확인 ▼

더보기
    void Start()
    {
        StartCoroutine(TestFunction());
    }

    IEnumerator TestFunction() 
    {
        for (int i = 0; i < 3; ++i)
        {
            Debug.Log("Hello World!");

            yield return new WaitForSeconds(2.0f);
        }
    }

 

게임이 멈추면 로그가 출력되지 않는 게 보통적인 게임이므로 WaitForSeconds를 사용.

 

 

문제 2. 

코루틴을 사용하여 IsReady가 true가 된 경우 준비완료 로그 출력하기

 

정답확인 ▼

더보기
    bool isReady = false;

    void Start()
    {
        StartCoroutine(TestFunction());
    }

    IEnumerator TestFunction() 
    {
        yield return new WaitUntil(() => isReady);

        Debug.Log("B 종료");

    }

 

코루틴에서 WaitUntill, WaitWhile을 쓰려면 람다식을 사용하여 해당 변수를 전달 받아야함.

 

문제 3.

코루틴 함수 A와 B가 있다. A는 5초뒤 "A 종료" 로그가 출력되야 하며, B는 A가 끝난 뒤 "B 종료" 를 출력하여야 한다.

 

정답확인 ▼

더보기
    void Start()
    {
        StartCoroutine(TestFunctionB());
    }
    
        IEnumerator TestFunctionA() 
    {
        yield return new WaitForSeconds(5.0f);

        Debug.Log("A 종료");
    }

    IEnumerator TestFunctionB() 
    {
        yield return StartCoroutine(TestFunctionA());

        Debug.Log("B 종료");

    }

 

'Engine > Unity' 카테고리의 다른 글

Unity에서 csv 파일 읽어오기(엑셀, 메모장)  (2) 2025.07.08
Unity에서 JSON 사용하기  (1) 2025.07.07
Unity Drag & Drop  (0) 2025.02.19
Unity MathF  (0) 2025.02.17
Unity Transform  (2) 2025.02.07