Unity3D/유니티 공부

[Unity / C#] 코루틴(Coroutine)과 인보크(Invoke) 비교.

상연 2022. 4. 29. 03:25

목차

    Coroutine VS Invoke


    코루틴(Coroutine)

     

    [Unity / C#] 코루틴(Coroutine)

    코루틴(Coroutine) Coroutine 코루틴의 사용이유 일반적으로 유니티에서 함수를 호출하면 값을 반환하기 전에 실행이 완료되어버린다. 즉, 함수에서 수행되는 모든 Action이 하나의 Frame에서 발생하고

    wonsang98.tistory.com

    인보크(Invoke)

     

    [Unity / C#] 인보크(Invoke)

    인보크(Invoke) 단순히 게임이 아니더라도 개발을 하다보면 특정 함수를 일정시간 이후에 실행시켜야 할 필요가 생긴다. 이럴때 사용하는 기능이 인보크(Invoke)이다. 인보크는 아주 간단하게 함수

    wonsang98.tistory.com

     

    둘 다 Unity, C#에서 프로그래머가 함수를 원하는 시점에 지연하여 실행시킬 때 요긴하게 사용되는 기능이다.

    서로 비슷한 일을 수행하기 때문에 이 둘의 차이점이 무엇인지 어떤 것이 더 나은지에 대해 많은 사람들이 궁금해한다.

    결론만 놓고 보면 성능상으로는 코루틴(Coroutine)이 더 우세하다.

    하지만 이는 단순 성능상의 비교이고 비슷한 일을 하는 둘이지만 약간씩의 차이가 있다. 

    지금부터 알아보자.

     

    성능


    구체적인 수치와 자료는 없으나, 대개 코루틴(Coroutine)이 인보크반복(InvokeRepeating)보다  더 빠르다고 한다.

    그 이유에는 실행시킬 함수를 매개변수로 전달하는 과정에서 발생하는 것이라고 본다.

    코루틴의 경우에는 메서드 그 자체가 들어가지만, 인보크의 경우에는 Reflection을 사용하여 들어가기 때문에 여기서 성능의 차이가 발생하는 것이다.

    하지만, 현재 컴퓨터 기술은 매우 발전했고 제작하고자 하는 프로그램이 굉장히 최적화를 신경 써야 한다던지

    아니면 InvokeRepeating 혹은 Coroutine을 작동시키는 시점에 이미 다른 실행 흐름이 많다면 Coroutine을 선택하는 것이 조금 더 현명한 선택이 될 수는 있겠다.

     

    매개변수의 전달 및 사용의 유연성


      매개변수 전달
    인보크(Invoke) X
    코루틴(Coroutine) O

    코루틴은 매개변수를 받아 실행이 가능하지만, 인보크는 매개변수의 전달이 불가능하다.

    다만, 그만큼 코루틴의 실행보다는 인보크가 더 간편하다는 장점은 있다.

    반대로 말하면 코루틴은 인보크보다 사용방법에 있어서는 조금 더 복잡할지언정 더 유연하게 사용이 가능하다.

    InvokeRepeating의 경우에는 반복을 시키고 취소시키려면 CancelInvoke라는 함수를 따로 호출해줘야 하지만

    코루틴의 경우에는 프로그래머가 여러 조건을 걸어 좀 더 원하는 시점에서 사용하고 끌 수 있다.

     

    오브젝트 비활성화 시


      오브젝트 비활성화 시
    인보크(Invoke) 멈추지 않음
    코루틴(Coroutine) 멈춤

    스크립트를 컴포넌트로 갖는 오브젝트가 비활성화되었을 시에 차이가 있다.

    이 점에 유의해서 둘 중 더 맞는 것을 선택해야 한다.

    코루틴(Coroutine)의 경우 오브젝트를 비활성화 후 활성화하더라도 코루틴이 재실행되지는 않으므로 꼭 유의하자.

    이와 관련이 있는 부분에서 조금 관심을 갖고 봐야 할 부분이 있다.

    OnEnable() 을 사용할 때 조심하자

    OnEnable() 즉, 객체가 활성화될 때 실행되는 함수인데 이 안에 인보크(Invoke) 혹은 코루틴(Coroutine)을 넣었고

    객체를 비활성화하고 다시 활성화하게 되면 어떻게 될까?

    private void OnEnable()
        {
            InvokeRepeating("tryInvoke", 1.0f, 1.0f);
            StartCoroutine(tryCoroutine());
        }
        void tryInvoke()
        {
            Debug.Log($"Invoke 실행! {Time.time}");
        }
    
        IEnumerator tryCoroutine()
        {
            while (true)
            {
                Debug.Log($"Coroutine 실행!!{Time.time}");
                yield return new WaitForSeconds(1.0f);
            }
        }

     

    4초가 지난 시점에서 오브젝트를 비활성화시켰다.

    위에서 이야기한 것과 동일하게, 코루틴은 동작을 정지하였으며, 인보크는 계속해서 실행 중이다.

    그럼 이 상태에서 다시 오브젝트를 활성화시켜보겠다.

    코루틴은 OnEnable() 함수에 의해 다시 실행되어 하나만이 돌아가지만

    인보크는 오브젝트 비활성화 이전에 실행되었던 것과 더불어서 두 개가 돌아간다.

     

    이러한 두 기능의 차이를 잘 이해하여 적재적소에 잘 활용해보자.