🌟 Unity 코루틴(Coroutine) 😋 🌟
안녕하세요. 박민성입니다. 🤗
오늘은 Unity에 코루틴(Coroutine)에 대해서 글을 쓰고자 합니다. 🤔
코루틴 또한 그냥 그런갑다 하고 사용하고 있었는데여 코루틴에 대해서 어느정도 알고있지만
그 어느정도 아는 것이 새로운 궁금증을 자아내고 찾아보며 공부하게 된거 같습니다.
1. 코루틴이란?
코루틴은 메서드 실행을 중간에 멈췄다가 나중에 그 위치부터 다시 실행할 수 있도록 하는 Unity의 실행 방식입니다.
private IEnumerator TestCoroutine()
{
Debug.Log("시작");
yield return null;
Debug.Log("다음 프레임");
}
실행은 StartCoroutine()을 사용해서 코루틴을 실행시킬 수 있습니다.
StartCoroutine(TestCoroutine());
코루틴에서는 yield return을 이용해 실행을 중간에 멈출 수 있으며 StartCoroutine()을 통해 Unity가 해당 코루틴을 관리하도록 합니다.
2. 일반 메서드와 코루틴의 차이
일반 메서드
private void Test()
{
Debug.Log("시작");
Debug.Log("끝");
}
일반 메서드는 호출되면 내부 코드가 끝날 때까지 한 번에 실행됩니다.
중간에 시간이 지나기를 기다리거나 다음 프레임까지 멈출 수 없습니다.
코루틴
private IEnumerator TestCoroutine()
{
Debug.Log("시작");
yield return null;
Debug.Log("다음 프레임");
}
코루틴은 yield return을 기준으로 실행을 나눌 수 있습니다.
코루틴은 실행 흐름을 여러 시점이나 프레임으로 나누는 기능입니다.
3. IEnumerable과 IEnumerator 간단히 알아보기
코루틴 메서드를 사용할 때 항상 반환 값을 IEnumerator을 사용해 왔습니다.
IEnumerator는 뭘까요??
일단 IEnumerator를 알기 전에 IEnumerable을 알아야 합니다.
IEnumerable<T>
IEnumerable<T>는 여러 값을 차례대로 제공할 수 있는 대상을 의미합니다. (인터페이스)
List, Queue, Stack 등 자료 구조들이 IEnumerable을 구현하고 있습니다.

IEnumerator<T>
IEnumerator<T>는 실제로 순회를 진행하면서 현재 위치를 기억하는 객체입니다.
MoveNext();
Current;
IEnumerator 안에는 MoveNext()와 Current가 있는데요.
MoveNext()는 다음 요소로 이동하고 Current는 현재 요소를 가져옵니다
둘의 관계는
IEnumerable<T>은 순회할 수 있는 대상이고
IEnumerator<T>는 실제 순회를 진행하는 객체입니다.
비유를 하자면
IEnumerable = 책
IEnumerator = 책갈피를 가지고 한 장씩 읽는 사람으로 비유할 수 있을 것 같습니다.
4. C#의 yield란?
yield는 Unity 전용이 아닌 C# 키워드입니다.
yield를 사용하면 값을 하나 반환하고 현재 위치에서 멈춘 뒤에 다음 요청이 왔을 때 이어서 실행할 수 있습니다.
private IEnumerable<int> GetNumbers()
{
yield return 10;
yield return 20;
yield return 30;
}
foreach (int number in GetNumbers())
{
Debug.Log(number);
}
첫 번째 값 요청 -> 10을 반환하고 멈춤 -> 두 번째 값 요청 -> 이전 위치부터 이어서 20을 반환하고 멈춤 -> 세 번째 값 요청 -> 다시 이어서 30을 반환하고 멈춤
이런식으로 동작합니다.
yield는 값을 반환하면서 메서드를 완전히 종료하지 않고 현재 실행 위치와 상태를 유지할 수 있게 하는 C# 키워드입니다.
5. Unity 코루틴에서 IEnumerator를 사용하는 이유
Unity에서 코루틴을 사용해봤다면 반환 값이 IEnumerator인걸 아실텐데여
private IEnumerator TestCoroutine()
{
Debug.Log("A");
yield return null;
Debug.Log("B");
}
Unity는 반환받은 IEnumerator를 통해서
현재 어디까지 실행했는지,
현재 반환된 값이 무엇인지,
다음 단계가 남아 있는지,
언제 다시 실행해야 하는지. 이런 정보들을 관리할 수 있습니다.
일반 반복자에서는 IEnumerator가 다음 요소 위치를 기억했다면
Unity 코루틴에서는 다음 실행 위치를 기억하는 데 사용됩니다.
IEnumerable이 아닌 IEnumerator인 이유는
Unity 코루틴은 자류 구조처럼 컬렉션 전체를 제공하려는 것이 아니라
하나의 실행 흐름을 단계별로 진행하려는 목적이기 때문입니다.
6. StartCoroutine()의 역할
코루틴 메서드를 그냥 호출하는 것과 StartCoroutine()으로 실행하는 것은 다릅니다.
TestCoroutine();
StartCoroutine(TestCoroutine());
StartCoroutine()을 사용하지 않고 호출하면 IEnumerator 객체를 얻을 뿐 Unity가 실행 과정을 관리하지 않습니다.
StartCoroutine()을 사용하여 호출하면 Unity가 해당 IEnumerator를 받아 코루틴으로 관리하게 됩니다.
그래서 StartCoroutine() 사용하지 않으면 yield가 작동되지 않아서 오류가 나지 않더라도 버그가 생겼던 이유였습니다. (저의 예기입니다 ㅎㅎ;)
7. yield break
yield break는 코루틴이나 반복자 메서드를 즉시 종료합니다.
private IEnumerator AttackRoutine()
{
if (target == null)
{
yield break;
}
yield return new WaitForSeconds(1f);
target.TakeDamage(10);
}
yield return null은 실행을 일시 중단 시키고 나중에 다시 이어서 실행한다면
yield break는 실행을 완전히 종료시켜서 이후 코드가 실행되지 않습니다.
그냥 일반 메서드에 return과 비슷한 종료 역할을 하는 것입니다.
오늘은 Unity 코루틴(Coroutine)에 대해서 알아보았는데요~!
진짜 코루틴 내부동작을 공부하면서 살짝 머리가 아팠습니다...
이 글에 쓸려고 했지만 못 들어간 내용들도 있고.. (코루틴은 스레드가 아닙니다. 등)
제가 여러가지로 완벽하게 설명하여 글로 작성을 하지 못할 것 같아서...
다음에 시간되면 작성해보려고 합니다!
내일은 더욱 알차게 보내고 작성해보도록 하겠습니다.
봐주셔서 감사합니다. ☺️