본문 바로가기

유니티

[유니티] 코루틴(Coroutine)에 대해 알아보자

코루틴이란?

코루틴은 유니티로 프로그래밍을 할 때 많이 사용되는 문법으로, 시간의 경과에 따른 명령을 주고싶을 때 사용하게 되는 문법입니다.

Update문으로 프레임마다 적용하여 시간을 계산하는 방법이 있지만 코루틴을 사용하면 훨씬 간단해집니다.

예를 들어서

1초마다 카운터를 출력하는 로그를 Update함수를 통해 구현한다고 친다면,

    float t;
    int counter;
    void Update()
    {
        t+= Time.deltaTime;
        if (t >= 1)
        {
            Debug.Log(counter);
            counter++;
                t = 0;
        }
    }

이런 식으로 구현이 됩니다.

1초마다 출력이 된다.

하지만 업데이트 함수는 매 프레임마다 업데이트 함수를 가지고 있는 오브젝트마다 실행을 하기 때문에, 비용이 많이 들게 됩니다.

이런 상황에서 코루틴을 쓰게 되면 적은 비용으로 해결을 할 수 있습니다.

코루틴 호출 방법

        StartCoroutine("CoroutineName");
        StartCoroutine(CoroutineName());//매개변수를 넣는것 또한 가능하다.

CoroutineName이라는 코루틴이 정의되어 있다면 이런 식으로 호출하면 됩니다.

코루틴 정의

IEnumerator CoroutineName()
    {
        yield return null;
    }

먼저 IEnumerator로 시작되며, 중간에는 반환을 한다는 yield return이 포함되어야만 합니다.

yield return은

  • yield return null;
  • yield return new WaitForSeconds(t);
  • yield return new WaitForSecondsRealtime(t);
  • yield break;

등등이 있는데

null을 반환하면 다음 프레임에 이어지는 내용의 실행이 된다는 뜻이고,

yield return new WaitForSeconds(t), yield return new WaitForSecondsRealtime(t) 는 둘 다 t초뒤에 이어지는 내용이 실행이 된다는 뜻인데,

둘의 차이점은 전자는 유니티 내부의 timescale의 영향을 받고, 후자 유니티 내부의 timescale의 영향을 받지 않는 실제 시간이 흐른 뒤 실행이 된다는 점이 차이점입니다.

yield break는 다른 함수의 return 과 같은 역할을 한다고 생각하면 됩니다.

그 외에도 몇가지가 있지만, 대부분 저 종류로 해결이 가능합니다.

 

코루틴 예제

코루틴을 활용해서 위의 Update문과 같은 기능을 적용시키게 한다면,

 

private void Start()
    {       
        StartCoroutine("CoroutineName");
    }
    IEnumerator CoroutineName()
    {
        int counter=0;

        while (true)
        {
            Debug.Log(counter);
            counter++;
            yield return new WaitForSeconds(1);
        }

    }

위와 같이 작성을 하면 1초마다 counter값을 로그로 출력하는 기능을 구현 할 수 있습니다.

코루틴은 update문 보다 훨씬 적은 비용을 할애하면서 동작이 가능하다는 점에서 굉장히 유용하게 쓸 수 있습니다. 

 

코루틴 종료

StopCoroutine("CoroutineName");
StopCoroutine(CoroutineName());

시작과 마찬가지로, 특정 코루틴의 종료도 가능하다.

 

위의 예제와 병합해서 예시를 보이면,

 

예제코드

 private void Start()
    {       
        StartCoroutine("CoroutineName");
        Invoke("CoroutineStop", 3); //시작 훟 3초뒤에 CoroutineStop이라는 함수를 호출함.
    }
    IEnumerator CoroutineName()
    {
        int counter=0;

        while (true)
        {
            Debug.Log(counter);
            counter++;
            yield return new WaitForSeconds(1);
        }
    }
    void CoroutineStop() //시작 후 3초뒤에 호출 될 함수
    {
        Debug.Log("코루틴 종료");
        StopCoroutine("CoroutineName");     
    }

 

이런식으로 코루틴 종료도 가능합니다.