study/코딩

[c# 개념] 코루틴(Coroutine)

lucykorea414 2023. 5. 30. 22:59
728x90

만약 이런 코드가 있다고 하자

그러면 여기서 제어권의 이동은 다음과 같다.

  1. Start() 시작
  2. Start() -> LoopA()
  3. LoopA() -> Start()
  4. Start() -> LoopB()
  5. LoopB() -> Start()
  6. Start() 끝

이때 LoopA()와 LoopB()를 동시에 실행시킬 수 있는 기능이 코루틴이다!

(일종의 병렬 처리라고 생각하면 된다, 실제로 병렬은 아니고 속임수임)

위에서 작성한 코드를 코루틴으로 바꿔보자!

이때 코드를 실행하게 되면

1초에 한번씩 i와 x의 값이 동시에 번갈아가면서 커지는게 출력이 된다!

만약 코루틴을 중단하고 싶다면?

방법1)

public class Test : MonoBehaviour
{
    Coroutine myCoroutine1;  //Coroutine 전역변수 선언
    Coroutine myCoroutine2;

    void Start()
    {
        myCoroutine1 = StartCoroutine(LoopA());  //StartCoroutine()라는 메서드 안에 넣어줘야함
        myCoroutine2 = StartCoroutine(LoopB());

        StartCoroutine(Stoooop());  //코루틴 중단 호출
    }

    IEnumerator LoopA()
    {
        for(int i=0; i < 10; i++)
        {
            print("i의 값: " + i);
            yield return new WaitForSeconds(1f);  //1초 대기하고 print찍히고 다시 대기하고~
            //yield return 은 일정 시간 만큼 대기 시켜주는 문법이다.
            //이때 null을 넣게 되면 한 프레임을 대기하게 된다.
            //new WaitForSeconds(nf)를 넣으면 괄호 안에 넣은 수 만큼 n초를 기다린다.
        }
    }

    IEnumerator LoopB()
    {
        for (int x = 0; x < 10; x++)
        {
            print("x의 값: " + x);
            yield return new WaitForSeconds(1f);  //1초 대기하고 print찍히고 다시 대기하고~
        }
    }

    IEnumerator Stoooop()
    {
        yield return new WaitForSeconds(2f);
        StopCoroutine(myCoroutine1);  // 2초 뒤 LoopA() 중단

        yield return new WaitForSeconds(2f);
        StopCoroutine(myCoroutine2);  // 2+2초 뒤 LoopB() 중단

    }
}

이런식으로 코드를 작성해주면 된다!

이 코드를 실행시키면 i와 x가 출력이 되다가 i는 1까지만 나오고 중단이 되고 x는 3까지만 나오고 중단이 된다

방법2)

public class Test : MonoBehaviour
{
    Coroutine myCoroutine1;

    void Start()
    {
        myCoroutine1 = StartCoroutine(LoopA());  //StartCoroutine()라는 메서드 안에 넣어줘야함
        StartCoroutine("LoopB");  //문자열로 실행시키기

        StartCoroutine(Stoooop());
    }

    IEnumerator LoopA()
    {
        for(int i=0; i < 10; i++)
        {
            print("i의 값: " + i);
            yield return new WaitForSeconds(1f);  //1초 대기하고 print찍히고 다시 대기하고~
            //yield return 은 일정 시간 만큼 대기 시켜주는 문법이다.
            //이때 null을 넣게 되면 한 프레임을 대기하게 된다.
            //new WaitForSeconds(nf)를 넣으면 괄호 안에 넣은 수 만큼 n초를 기다린다.
        }
    }

    IEnumerator LoopB()
    {
        for (int x = 0; x < 10; x++)
        {
            print("x의 값: " + x);
            yield return new WaitForSeconds(1f);  //1초 대기하고 print찍히고 다시 대기하고~
        }
    }

    IEnumerator Stoooop()
    {
        yield return new WaitForSeconds(2f);
        StopCoroutine(myCoroutine1);

        yield return new WaitForSeconds(2f);
        StopCoroutine("LoopB");  //문자열로 중단하기
    }
}

이렇게 문자열로 하는 방법도 있다! (신기 했음)

문자열로 해도 똑같이 적용이 됩니다.

이때, 방법1과 방법2의 차이점을 간단하게 말하자면 방법2(문자열)가 조금 더 과부하에 걸린다!

문자열 같은 경우에는 최대 넘길 수 있는 파라미터의 갯수가 1개이다.

함수처럼 넘겨준다면 파라미터는 여러개 있을 수 있다!

방법3)

public class Test : MonoBehaviour
{
     private IEnumerator myCoroutine1;

    void Start()
    {
        myCoroutine1 = LoopA();  //이 방법은 파라미터가 많을때 유리하다!
        StartCoroutine(myCoroutine1);
        StartCoroutine("LoopB");  //문자열로 실행시키기

        StartCoroutine(Stoooop());
    }

    IEnumerator LoopA()
    {
        for(int i=0; i < 10; i++)
        {
            print("i의 값: " + i);
            yield return new WaitForSeconds(1f);  //1초 대기하고 print찍히고 다시 대기하고~
            //yield return 은 일정 시간 만큼 대기 시켜주는 문법이다.
            //이때 null을 넣게 되면 한 프레임을 대기하게 된다.
            //new WaitForSeconds(nf)를 넣으면 괄호 안에 넣은 수 만큼 n초를 기다린다.
        }
    }

    IEnumerator LoopB()
    {
        for (int x = 0; x < 10; x++)
        {
            print("x의 값: " + x);
            yield return new WaitForSeconds(1f);  //1초 대기하고 print찍히고 다시 대기하고~
        }
    }

    IEnumerator Stoooop()
    {
        yield return new WaitForSeconds(2f);
        StopCoroutine(myCoroutine1);

        yield return new WaitForSeconds(2f);
        StopCoroutine("LoopB");  //문자열로 중단하기
    }
}

이 방법은 중단하는 방법은 똑같지만 IEnumerator 변수를 하나 선언해서 그것을 활용하는게 방법1과 조금 다르다! 이 방법은 코드에도 적었다싶이, LoopA의 파라미터가 많을 때 유리하다. (매번 호출할때 마다 파라미터를 다 쓸 필요가 없으니)

그리고 마지막 방법4)

StopAllCoroutine();

클래스 내에 있는 모든 코루틴들을 중단시킨다.

728x90