TIL(2024,05,22) 코루틴Coroutine

김보근·2024년 5월 22일

Unity

목록 보기
6/113

코루틴 (Coroutine)

코루틴이란?

코루틴을 사용하면 작업을 다수의 프레임에 분산할 수 있습니다. Unity에서 코루틴은 실행을 일시 정지하고 제어를 Unity에 반환하지만 중단한 부분에서 다음 프레임을 계속할 수 있는 메서드입니다.

대부분의 경우 메서드를 호출하면 실행을 완료한 뒤 호출한 메서드에 제어와 선택적 반환 값을 반환합니다. 즉 메서드 내에서 발생한 모든 행동은 단일 프레임 업데이트 내에서 발생해야 합니다.

시간의 흐름에 따른 이벤트의 시퀀스나 절차상의 애니메이션을 포함하기 위해 메서드 콜을 사용하고자 하는 상황에서 코루틴을 사용할 수 있습니다.

하지만 코루틴은 스레드가 아니라는 점을 명심해야 합니다. 코루틴의 동기 작업은 여전히 메인 스레드에서 실행됩니다. 메인 스레드에 소요되는 CPU 시간을 줄이려면 다른 스크립트 코드에서와 마찬가지로 코루틴의 작업 차단을 방지하는 것이 중요합니다.

코루틴은 HTTP 전송, 에셋 로드, 파일 I/O 완료 등을 기다리는 것과 같이 긴 비동기 작업을 처리해야 하는 경우 코루틴을 사용하는 것이 가장 좋습니다.

https://docs.unity3d.com/kr/2021.3/Manual/Coroutines.html
(유니티 매뉴얼 참고)

코루틴 작성방법

코루틴은 IEnumerator 라는 반환형으로 시작하고 yield return이 반드시 함수 내부에 존재해야 한다.

IEnumerator 함수이름()
{
	//함수내용

	yield return // + 조건
}

yield return의 종류는 다양하다.

  • yield return null; : 다음 프레임에 실행 됨.

  • yield return new WaitForSeconds( float ); : 매개변수로 입력한 숫자에 해당하는 초만 큼 기다렸다가 실행됨.

  • yield return new WaitForSecondsRealtime( flaot ); : 매개변수로 입력한 숫자에 해당하는 초만큼 기다렸다가 실행됨.

  • 그외 : yield return + new WaitForFixedUpdate 등등..

  • yield break; : 코루틴을 끝내는

2번과 3번의 차이는

3번은 현실의 시간을 기준으로 체크하는 것이고, 2번은 유니티상에서의 시간을 기준으로 체크하는 것이다.

유니티에서 시간은 TimeScale을 사용해서 느리게하거나 빠르게 조절할 수 있는데, 이 값의 변화에 영향을 받는 것이 2번이고 무관한 것이 3번이다.

아래와 같이 작성하면 2초뒤 HP 를 회복하는 Heal이라는 코루틴 메소드가 완성된다.

IEnumerator Heal()
{
	yield return new WaitForSeconds( 2.0f );
    
    Hp += 10;
}

만약 해당 코루틴 내부에 for문이나 while문을 사용해준다면 마치 업데이트문 처럼 매 프레임마다 반복되게 할 수 있다.

Update문은 따로 동작하면서도 말이다.

만약, 업데이트문에 이런 반복문을 쓰게 되면 해당 반복이 끝날 때까지, 반복문 아래에 있는 코드들은 전혀 실행이 되지 않는다.

그러나 코루틴에서 반복문을 사용하면 Update와는 별도로 동작하기 때문에 모든 스크립트가 정상적으로 동작하게 된다.

코루틴 사용방법

그냥 일반 메소드들 처럼 단순하게 이름을 사용해서 쓸 수는 없다.

StartCoroutine( ); 을 사용해서 쓸 수 있다. ( ) 안에다가 매개변수를 넣는 것처럼 생성한 코루틴 이름을 적어주면 된다.

위에서 예로 만들었던 Heal( ) 코루틴을 사용하려면 다음과 같이 작성하면 된다.

StartCoroutine(Heal());
StartCoroutine("Heal");
이렇게 2가지 방법으로 사용할 수 있다.

정리

(정리) 원래는 함수 A가 다 끝나야 B로 넘어가고 B가 끝나야 C로 넘어가는데

코루틴을 쓰는 경우,

A를 10%만 처리하고 멈추고 다른 작업을 할수있습니다. 그러다가 적절한 때가 되면, A로 다시 돌아와서 멈췄던 10%에서 다시 시작합니다.

(얼만큼 처리하다가 양보할건지, 나중에 언제 다시 시작할지는 개발자가 컨트롤 가능.)

따라서 단일스레드인데, abc가 분할되서 처리되고 이게 너무 빨라서 마치 3개의 작업이 동시에 일어난것처럼 보임.

profile
게임개발자꿈나무

0개의 댓글