행복한 연어의 이야기

(Unity) 코루틴(Coroutine) 본문

IT/Unity

(Unity) 코루틴(Coroutine)

해피살몬 2020. 1. 14. 20:12

전에 이벤트함수실행순서 에 대해서 알아보았습니다.
그때 Yield 구문에 대해서 언급했었는데요.
그 Yield 구문을 사용하는 코루틴에 대해서 알아보고자 합니다.

코루틴(Coroutine) 이란?

  • C언어 등에서 일반적으로 사용하는 함수는 시작할 때 진입하는 지점이 하나 존재하고 함수가 모두 실행되거나, return 구문에 의해 종료되는 지점을 설정할 수 있습니다.
  • 이러한 함수를 Subroutine( 서브루틴 )이라 부르는데, 코루틴은 이를 더 일반화한 개념으로 진입하는 시점을 여러 개를 가질 수 있는 함수를 의미합니다. 개념적으로만 본다면 코루틴도 서브루틴의 한 종류라고 볼 수 있겠죠.
  • 함수가 실행되고 return 으로 종료되는 대신에 Yield 하면 Yield 한 부분을 기억했다가 나중에 Yield 된 지점부터 실행을 이어 갈 수 있습니다.

IEmumerator 와 yield 는 무엇인가?

  • 코루틴의을 사용하기 전에 IEnumerator와 yield 를 간단하게 설명하고 넘어가겠습니다.
  • IEmumerator : C#에서 컬렉션을 반복하기 위한 인터페이스입니다. yield 문을 만날 때까지 코루틴 내부에 있는 코드를 실행합니다.
  • yield return : 코루틴의 실행을 일시 정지하고 제어를 유니티에 넘겨줍니다. 다음 호출 때 이다음 지점에서 코드가 실행됩니다
  • 링크 : IEnumerator
  • 링크 : Yield

왜 사용할까?

  • 코딩을 하다 보면 매 프레임마다 실행되는 Update 함수에서 동작을 확인하는 것보다 일정 간격을 두고 확인해야 할 때가 있습니다.
  • 예를 들어 스킬 쿨타임을 5초라고 잡았을 때(1초의 60 프레임이라고 보고) Update에서는 if문을 300번을 체크할 것입니다. 코루틴은 더 간단하게 처리할 수 있습니다. 5초 후에 스킬을 활성화 시켜라 라고 말이죠.
  • 그렇다고 해도 5초 동안 아무것도 안 하고 쉬는 것은 아닙니다. 실제로 유니티는 매 프레임마다 올바른 시간이 경과되어있는지 검사를 하고 있죠.
  • 하지만 코루틴을 사용한다면 좀 더 편리하고 가독성 있게 처리할 수 있습니다.
  • 또한 코루틴은 비동기처럼 사용 할 수 있습니다. 유니티에서 멀티쓰레드를 지원하지 않기 때문에 (사용은 가능 하지만 Unity API 참조 시 작동 안 할 수 있습니다.) 코루틴을 권장 하고 있기도 합니다.

기본적인 사용방법


private IEnumerator tempCoroutine;
private void Start()
    {
        tempCoroutine = CoroutineA();
        StartCoroutine(tempCoroutine);
        StartCoroutine(CoroutineB());
        StartCoroutine("CoroutineC");
    }
  • 위 코드를 보시면 3가지의 StartCoroutine 종류를 보실 수 있습니다.
    3가지의 공통점은 모두 코루틴이 실행된다는 것이고 3가지의 차이점은 StopCoroutine 에 있습니다.

    1. CoroutineA() 만 Stop 하고 싶다면 StopCoroutine(tempCoroutine); 을 사용해야 합니다.
    2. CoroutineB() 만 Stop 하고 싶어도 방법이 없습니다.
    3. CoroutineC() 만 Stop 하고 싶다면 StopCoroutine("CoroutineC"); 을 사용해야 합니다.
  • 한 Class 안에 있는 모든 코루틴을 Stop 하고 싶다면 StopAllCoroutines(); 을 사용하시면 됩니다. CoroutineB()도 이때 Stop 됩니다.

  • 보통 Stop 할 일이 없는 코루틴의 경우 CoroutineB 의 방식을, Stop 할 일이 있는 코루틴의 경우 CoroutineA의 방식을 많이 사용합니다. CoroutineC 의 경우에는 오버헤드가 많이 걸리는 방식이라서 그렇습니다.

  • (유니티는 내부적으로 모든 함수들의 이름을 String 형으로 갖고 있는데 StopCoroutine(string)을 사용하면 모든 함수이름과 비교하기 때문입니다.)

기본적으로 제가 이해하고 조사한 내용을 적었습니다.

혹시라도 잘못되어 있으면 댓글로 알려주시면 감사하겠습니다!

Comments