본문 바로가기
게임개발/유니티 엔진

Coroutine(코루틴)

by do_ng 2024. 3. 7.

코루틴의 개념

로직을 실행하기 위해 최초로 main() 으로 진입하고 main 함수 안에서 차례대로 함수가 실행되고 함수가 종료되면 main 함수로 되돌아가서 다음 함수를 실행하는 방식으로 이루어진다. 

여기서 main 함수를 메인 루틴이라 부르고 메인 루틴 안에서 실행되는 모든 함수를 서브 루틴이라고 부른다. 

 

서브 루틴이 메인 루틴에 종속된 상태로 호출을 받는 입장이라고 한다면, 코루틴(Co-Routine)은 "Co" 라는 접두사 의미가 "공동의", "협력 관계" 이라는 것으로 메인 루틴과 대등한 관계에 있다.

위키피디아에서 코루틴의 정의는 다음과 같다. 

 

실행의 지연과 재개를 허용함으로써, 
비선점적 멀티태스킹을 위한 서브 루틴을 일반화한 컴퓨터 프로그램 구성요소
  • 비선점 : 하나의 프로세스가 CPU를 할당받으면 종료되기 전까지 다른 프로세스가 CPU를 강제로 차지할 수 없음
  • 선점 : 하나의 프로세스가 다른 프로세스가 점유중인 CPU를 강제로 차지할 수 있음

코루틴은 비선점적 멀티태스킹 방식을 사용하며 마치 여러작업을 동시에 처리하는 것(동시성)처럼 보일 수 있지만, 실제로는 A라는 작업을 해당부분까지 실행하다가 다른 작업으로 넘어가야 할 때 마지막으로 실행된 부분에서 체킹(나중에 여기부터 실행하겠다라는 표시)을 해놓은 다음 지연(일시중지)시키고 다시 A작업이 재개될때 체킹한 부분부터 실행된다. 

 

코루틴과 서브 루틴의 차이

프로그램은 여러 루틴의 조합으로 진행되는데, 메인 루틴과 서브 루틴으로 나뉜다.

  • 메인 루틴 : 프로그램의 전체 동작 부분으로 main 함수에 의해 수행되는 흐름
  • 서브 루틴 : main 함수 내에서 실행되는 개별 함수의 흐름

서브 루틴의 경우는 함수 호출시 저장된 메모리로 이동한 뒤 실행 후 로직이 다 수행되거나 반환문(return)을 만나면 함수가 종료되는 구조인데

 

코루틴은 함수 진입 후 반환문(return)이 없거나 코드가 끝까지 실행되지 않더라도 임의 지점에서 동작을 중단하고 이후 해당 지점에서부터 실행을 재개하는 방식으로 이루어진다. 

 

유니티에서 코루틴 사용법

class CoroutineTest : IEnumerable
{
    public IEnumerator GetEnumerator()
    {
        yield return null;
    }
}

함수의 반환 타입으로는 반드시 "IEnumerator"를 사용해야 하고, yield return 구문이 적어도 한 번 이상은 사용되야 한다. 

"yield"는 넘겨주다, 양도하다 라는 뜻으로 코루틴이 함수에 정의된 작업을 실행하다가 yield return 구문을 만나면 yield return [지정한 명령]을 실행시키고 코루틴을 호출했던 루틴으로 제어(메인루틴)의 권한을 넘겨준다.

 

여기서 yield return이 지정한 명령인 null은 코루틴을 호출한 호출자에게 1프레임을 양보하고 대기하라는 뜻으로 코루틴이 1프레임 동안 메인루틴의 권한을 가지고 있는 동안 코루틴을 호출한 호출자는 1프레임 동안 실행하지 않게 된다.

1프레임이 종료되면 메인루틴의 권한은 코루틴을 호출한 호출자에게 넘어간다.

 

 

코루틴 예제

Coroutine co;

protected override void Init()
{   
    co = StartCoroutine("ExplodeAfter4Seconds", 4.0f);
    Debug.Log("플레이어 이동");
    StartCoroutine("CoStopExplode", 2.0f);
}

IEnumerator CoStopExplode(float seconds)
{
    Debug.Log("Stop Enter");
    yield return new WaitForSeconds(seconds);
    Debug.Log("Stop Excute");
    if (co != null)
    {
        StopCoroutine(co);
        co = null;
    }            
}

IEnumerator ExplodeAfter4Seconds(float seconds)
{
    Debug.Log("Explode Enter");
    yield return new WaitForSeconds(seconds); // seconds 동안 해당 코루틴을 중지(중지 하는 동안 다른 작업을 수행하다가 정해진 초가 지나면 다시 해당 코루틴을 호출)
    Debug.Log("Explode Excute");
    co = null; // Explode 실행됬으니까 해당 코루틴 사용 X
}

플레이어가 해당 스킬을 쓰면 4초 뒤에 스킬이 나간다고 했을때 

코루틴에서 그 스킬을 시전하고 4초 뒤에 다시 코루틴으로 돌아와서 스킬을 실행시킴
코루틴을 사용하지 않는다면 4초가 지났는지 계속 검사하다가 스킬을 실행시키는 방법이 필요한데 4초가 지났는지 검사하는 동안은 다른 작업을 수행할 수 없다.
4초라는 시간이 낭비되고 있으므로 코루틴을 사용해서 멀티 태스킹 작업을 할 수 있다.

 

롤에서 코루틴을 사용한다고 하면
이즈리얼이 궁을쓰면 쿨타임이 1분이라고 했을때 궁을 다시 쓰기 위해서 1분을 기다려야 되는데 1분이 지났으면 궁을 다시 활성화 상태로 만드는 것을 코루틴으로 만들어서 최초에 궁을 썼을때 코루틴을 호출하고 나머지 1분은 다른 작업을 수행할 수 있도록 하다가 플레이어가 중간마다 신비한 화살로 적 유닛을 명중시키면 다시 코루틴을 호출해서 궁의 쿨타임을 감소시키고 만약에 궁의 쿨타임이 없어지면 코루틴을 종료하는 방식으로 사용하지 않을까 생각함

 


참고 1 : https://teddy.tistory.com/entry/%EC%BD%94%EB%A3%A8%ED%8B%B4%EC%9D%98-%EC%9D%B4%ED%95%B4

 

참고 2 : https://m.blog.naver.com/PostView.nhn?blogId=pxkey&logNo=221296053953&proxyReferer=https:%2F%2Fwww.google.com%2F

 

참고 3 : https://dev.gmarket.com/82

'게임개발 > 유니티 엔진' 카테고리의 다른 글

네비게이션 시스템  (0) 2024.03.10
Time.DeltaTime  (0) 2024.03.09
오브젝트 풀링(Object Pooling)  (0) 2024.03.06
UI 이벤트 시스템  (0) 2024.03.04
UI 자동화  (0) 2024.03.03