Unity - Coroutine) 복습을 위해 작성하는 글 2023-05-04

rizz·2023년 5월 4일
0

Unity

목록 보기
2/4

📒 갈무리 - 코루틴(Coroutine)

📌 코루틴이란?(Unity)

- 필요에 따라 일시 정지할 수 있는 함수

- 실행을 일시 중지하고 Unity에 제어 권한을 반환한 후, 다음 프레임에서 중단했던 위치에서 계속 진행할 수 있는 함수

- Unity는 진행 루틴을 가지고 있는데, 이 진행 루틴대로 코드를 실행하다가 StartCoroutine을 만나면 코루틴을 실행하여 진행 루틴에서 빠져나와 코루틴이라는 새로운 루틴을 진행한다. 이때 제어권을 코루틴에게 준다고 표현한다.

- yield를 통해서 Unity의 진행 루틴으로 돌아가면 제어권을 Unity의 진행 루틴으로 넘기는 것이다.

- 여러 처리를 동시에 병렬로 할 수 있도록 해준다. (실제로 병렬 처리가 이루어지는 것은 아니고, 빠르게 왔다 갔다 하면서 실행되기 때문에 병렬 처리 되는 것처럼 보여지는 것)

- 보통 코드를 짜면 스크립트의 절차대로 진행되지만, 코루틴은 매인 동작과 상관없이 병렬처럼 진행될 수 있도록 한다.

 

📌 코루틴 사용 조건

1. 반환형은 IEnumerator 이어야 한다.

2. yield return이 반드시 존재해야 한다.

 

📌 yield

yield return null : Update()가 끝나면 실행 (한 프레임 대기)

yield return new WaitForSeconds(float) : 매개변수의 숫자에 해당하는 초만큼 만큼 대기하고 실행

yield return new WailtforSecondsRealtime(float) : 매개변수의 숫자에 해당하는 초만큼 대기하고 실행 (Time.timeScale의 영향을 받지 않는 절대적인 시간을 의미)

yield return new WaitForFixedUpdate() : FixedUpdate()가 끝나고 실행

yield return WaitForEndOfFrame() : 모든 Update()가 끝나고 화면 렌더링까지 끝났을 때 실행

yield return new WaitUntil() : 매개변수의 조건이 true일 때 실행 (실행 위치는 Update()와 LateUpdate() 이벤트 사이)

yield return new WaitWhile() : 매개변수의 조건이 false일 때 실행 (실행 위치는 Update()와 LateUpdate() 이벤트 사이)

yield return StartCoroutine(string) : 매개변수의 이름을 가진 코루틴이 끝날 때까지 대기하고 실행

yield return new www(string) : 매개변수의 이름을 가진 웹의 통신 작업이 끝날 때가지 대기

yield return new Asyncloeration : 비동기 작업이 끝날 때까지 대기(씬 로딩)

 

📌 코루틴 사용 예제

// Unity C# Script

    void Start()
    {
    	// 코루틴에게 제어권을 넘김.
        StartCoroutine(CoroutineTest());
    }

    // IEnumerator를 반환
    private IEnumerator CoroutineTest()
    {
        // 플레이 버튼을 눌렀을 때 동작 시간.
        Debug.Log($"1 : {Time.realtimeSinceStartup}");
        yield return null; // 한 프레임 대기 후 실행
        Debug.Log($"2 : {Time.realtimeSinceStartup}");
        yield return new WaitForSeconds(1f); // 1초 대기 후 실행
        Debug.Log($"3 : {Time.realtimeSinceStartup}");
    }

Output:
1 : 3.019858
2 : 3.032970
3 : 5.057276

// 코루틴의 1초는 정확한 1초로 떨어지지 않기 때문에 (보통은 1초 이상 걸림)
// 실제 계산이나 정교한 계산을 할 때는 코루틴을 쓰지 않는다.
// 연출할 때 유용하게 사용한다.

다중 코루틴

// Unity C# Script

    void Start()
    {
        // 메소드 이름을 넘겨줄 수도 있다.
        // 실무에서는 오타 때문에 이름을 넘기는 것은 잘 사용하지 않음.
        // 같은 구문.
        StartCoroutine(CoroutineTest());
        StartCoroutine("CoroutineTest"); 
    }

    private IEnumerator CoroutineTest()
    {
        Debug.Log($"1 : {Time.realtimeSinceStartup}");
        yield return null;
        Debug.Log($"2 : {Time.realtimeSinceStartup}");
        yield return new WaitForSeconds(1f);
        Debug.Log($"3 : {Time.realtimeSinceStartup}");

        // 코루틴을 실행하는 주체는 StartCoroutine을 호출하는 스크립트인데,
        // 결국에는 GameObject에서 코루틴을 관리하게 된다.
    }
    
Output:
1 : 3.004708
1 : 3.009927
2 : 3.019537
2 : 3.019891
3 : 4.102481
3 : 4.102903

// 두 개의 코루틴이 별개로 동작하게 된다.

코루틴과 코루틴 사이에서의 코루틴 정지

// Unity C# Script

    void Start()
    {
        Coroutine coroutine = StartCoroutine(CoroutineTest());

        StartCoroutine("CoroutineTest");

        StopCoroutine(coroutine); // 코루틴 정지.
    }

    private IEnumerator CoroutineTest()
    {
        Debug.Log($"1 : {Time.realtimeSinceStartup}");
        yield return null;
        Debug.Log($"2 : {Time.realtimeSinceStartup}");
        yield return new WaitForSeconds(1f);
        Debug.Log($"3 : {Time.realtimeSinceStartup}");
    }
    
Output:
1 : 3.023257 // 첫 번째 코루틴 실행하고 StopCoroutine을 만나 정지.
1 : 3.028298 // 두 번째 코루틴 실행.
2 : 3.037791
3 : 5.273876

코루틴과 코루틴 사이에서의 인터벌

// Unity C# Script

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

    private IEnumerator CoroutineTest()
    {
        Debug.Log($"1 : {Time.realtimeSinceStartup}");

        // CoroutineTest 코루틴 동작중에 CoroutineTest2를 실행.
        // CoroutineTest2를 마치고 CoroutineTest를 마저 실행.
        yield return StartCoroutine(CoroutineTest2());
        
        Debug.Log($"2 : {Time.realtimeSinceStartup}");
        yield return new WaitForSeconds(1f);
        Debug.Log($"3 : {Time.realtimeSinceStartup}");
    }

    private IEnumerator CoroutineTest2()
    {
        Debug.Log($"4 : {Time.realtimeSinceStartup}");
        yield return null;
        Debug.Log($"5 : {Time.realtimeSinceStartup}");
        yield return new WaitForSeconds(1f);
        Debug.Log($"6 : {Time.realtimeSinceStartup}");
    }
    
Output:
1 : 3.063264
4 : 3.068327
5 : 3.078072
6 : 5.415286
2 : 5.415732
3 : 6.419126

 

📌 코루틴 사용 주의점

- 코루틴이 종료되는 시점에 특정 시작되는 동작이나 함수가 호출된다면 그 동작에 대해 주석을 남겨 협업하는 개발자에게 알리는 것이 좋다.

- 코루틴이 종료되는 시점에 시작되는 동작이나 호출되는 함수는 코루틴에서 호출되기 때문에 어느 시점에 호출되는지 코드로 파악하기 어려울 수 있기 때문이다.

profile
삼겹살_치킨_햄버거_피자

0개의 댓글