코루틴이란?
코루틴을 사용하면 여러 프레임에 현재 함수의 작업을 분산하여 진행할 수 있다. 함수 실행 중 yield return을 사용하여 작업을 일시 중단한 후, 다른 프레임/시간에 제어권을 다시 넘겨받아 사용하는 식이다.
쓰레드와의 차이점은, 코루틴은 메인 스레드상에서 수행된다는 것이다.
쓰레드의 경우 둘, 혹은 여러개의 쓰레드가 각자의 작업을 맡아 수행한다면,
코루틴의 경우 한 개의 쓰레드가 ABABABAB...형식으로 각각의 작업을 조금씩 나누어 수행한다.
쓰레드
- 별개 쓰레드에서 동작한다.
- 동시에 여러개의 일을 처리할 수 있다.
- 쓰레드는 선점형이다.
- 일을 하는동안에도 다른 쓰레드가 돌아가고 있다.
- 공유 메모리를 사용할 경우, 서로의 접근이 겹칠 수 있다.
- Lock을 사용할 경우, 먼저 접근한 쓰레드가 우선적으로 사용하게 된다.
- 비동기적이다 = 동시에 수행된다.
코루틴
- 단일 쓰레드에서 동작한다.
- 여러개의 일을 나누어, 하나씩 처리한다.
- 코루틴은 비선점형이다.
- 현재 코루틴 동작이 끝날때까지, 다른 코루틴들은 대기하게 된다.
- 동시에 동작하지 않으므로, 메모리 접근이 겹칠 일이 없다.
- 현재 동작하고 있는 코루틴이 메모리를 사용하고 있을 것이다.
- 비동기적이 아니다 = 동시에 수행되지 않는다.
코루틴 선언법
IEnumerator ParticleFadeOut()
{
SpriteRenderer Renderer = this.GetComponent<SpriteRenderer>();
Color color = Renderer.color;
while(color.a > 0.0f)
{
color.a -= 0.2f;
Renderer.color = color;
yield return new WaitForSeconds(0.1f);
}
}
- 코루틴의 리턴 타입은 IEnumerator(열거자)로 선언한다.
- 함수 동작 중 수행을 중단할 때, yield return으로 return한다.
- 해당 방식으로 리턴할 경우, 그 위치에서 활동이 중단된 후 다시 돌아온다.
- Yield의 종류는 다음과 같다
- yield return null; -> 다음 프레임에 바로 시작
- yield return new WaitForSeconds(float) -> 일정 시간동안 대기
- yield return break; -> 코루틴 종료
- yield return new WaitForEndOfFrame();
- 모든 카메라와 GUI가 렌더링을 완료한, 프레임의 바로 직전에 다시 실행한다.
- 현재 화면을 저장하여 활용할 필요가 있을때 사용할 수 있다.
- yield return new WaitForFixedUpdate();
- 다음 FixedUpdate()가 호출될 때까지 기다린다.
- yield return new WaitUntil(조건문);
- 해당 조건문이 true가 될 때까지 기다린다.
- 조건문은 Update ~ LateUpdate 사이에 실행되어진다.
- yield return new WaitWhile(조건문);
- 해당 조건문이 true인 동안 기다린다
- 조건문은 Update ~ LateUpdate 사이에 실행된다.
코루틴의 사용법
//호출방법
StartCoroutine(ParticleFadeOut());
StartCoroutine("ParticleFadeOut");
//중단방법
Coroutine particleCorutine;
particleCorutine = StartCoroutine(ParticleFadeOut());
StopCoroutine(particleCorutine);
- 코루틴 호출시에는, 함수명을 호출하거나 함수명을 String으로 호출하는 형태로 선언한다.
- 코루틴 중지시에는 Corutine 변수가 필요하므로, 중단할 필요가 있을 경우 미리 선언하여 코루틴 시작 시 저장해둔다.
주의 사항
- 코루틴이 돌아가고 있던 객체가 파괴될 시에는 코루틴이 자동으로 중단되지만, 스크립트가 Disable될 때에는 중단되지 않는다.
- 스크립트가 중단될 일이 있을 경우 별도의 종료 호출이 필요하다.
- 오브젝트가 활성화 되어있지 않은 상태에서 코루틴이 활성화될 경우 에러가 발생할 수 있다.
- 오브젝트를 생성(Instantiate)된 직후에 별도의 함수로 코루틴을 호출할 경우, 에러가 발생할 수 있다.
- 프리팹으로 생성한 오브젝트에서 코루틴을 호출할 일이 있다면, Start()에서 코루틴을 호출하게 만들어 확실히 생성된 후 코루틴을 생성하게 만드는 것이 좋을것이다.
코루틴 사용의 장점
- Update 루프를 최적화 할 수 있다.
- 코드 정리를 수행할 수 있다.
코루틴 사용의 단점
- 가비지가 많이 생성된다.
- StartCoroutine을 사용할 때, 엔진 내부적으로 가비지가 다량 생성된다고 한다. -> 확인 필요
- 위의 소스 코드를 확인하면, yield return new ~ 의 형식으로 대기가 진행됨을 알 수 있다. yield return이 진행될때마다 새로운 인스턴스이 생성되기 때문에, 가비지 생성 문제가 생기게된다.
- 해당 문제를 해결하기 위해, Wait 인스턴스를 미리 만들어둔 뒤 캐싱하여 사용할 수 있다.
같이 보기
https://docs.unity3d.com/Manual/Coroutines.html
'Programming > Unity' 카테고리의 다른 글
유니티 오브젝트 파괴 / Gameobject.Destroy() (0) | 2022.03.02 |
---|