닷넷은 멀티쓰레드를 지원하고, 닷넷을 사용하는 유니티는 단일 쓰레드로 동작한다.
멀티쓰레드가 있는 코드는 버그 발생률이 높아지고, 멀티쓰레드간 교착 상태 경합 등 신경써야할 부분이 많아진다.
그렇다면 어떻게 멀티 태스킹을 손쉽게 구현할 수 있을까?
바로, 코루틴(Coroutine)을 사용해 멀티 쓰레드를 흉내낼 수 있다.
'쓰레드를 사용하지 않고, 멀티 태스킹을 가능하게 한다.' 이게 어떻게 가능할까?
일반적으로 함수가 호출되고 끝나는 서브루틴 개념과 다르게 yield return을 사용해
해당하는 위치를 기억하고 다음 호출 때 그 곳부터 다음 부분을 실행할 수 있도록 하는 것이다.
그래서 여러 개의 코루틴을 동작시키고 각기 다른 시점에 yield가 반환되도록 한다면
마치, 여러개의 쓰레드가 동시에 동작하는 것과 같은 효과가 나타나게 된다.
다음은 1초마다 로그를 찍는 함수를 코루틴으로 구현한 것이다.
private IEnumerator SecondLog()
{
while (true)
{
yield return new WaitForSeconds(1);
Debug.Log("This is Log!");
}
}
한 가지, 거슬리는 문제가 있다.
new연산자를 루프안에서 반복 사용하는 것이다. (가비지 컬렉터가 좋아하지 않는 코드다)
이렇게 바꾸면 어떨까?
private IEnumerator SecondLog()
{
WaitForSeconds sec = new WaitForSeconds(1);
while (true)
{
yield return sec;
Debug.Log("This is Log!");
}
}
[ 코루틴의 시작과 종료 ]
StartCoroutine(string methodName); 으로 코루틴을 사용하고,
StopCoroutine(string methodName); 으로 중지하면 한 개의 파라미터를 넘길 수 있고, Object로 넘기게 된다.
Object는 언박싱이 일어나 가비지를 생성하므로, 성능저하를 불러올 수 있다.
이런 단점을 가지고도 사용하는 이유는 'StopCoroutine함수로 코루틴(Coroutine)을 중지할 수 있다'는 편리함때문이다.
하지만, IEnumerator 인스턴스를 이용하면 언박싱이 일어나지 않고, 코루틴(Coroutine)을 중지시킬 수 있다.
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour
{
IEnumerator coroutine;
void Start()
{
coroutine = Test();
StartCoroutine(coroutine);
}
public IEnumerator Test()
{
while (true)
{
yield return new WaitForSeconds(1);
}
}
void Update()
{
If (Input.GetKeyDown("space")
{
StopCoroutine(coroutine);
}
}
}
※코루틴(Coroutine) 사용 시 주의사항
1. 코루틴 함수는 일반 함수처럼 실행되지 않고, 반드시 StartCoroutine을 사용해 호출한다.
2. Time Scale의 영향을 받는다.
Time Scale이 1인 상태에서 WaitForSeconds(1)은 1초를 대기하지만, 0.5일 때는 2초를 대기한다.
3. StartCoroutine을 호출하는 스크립트가 붙은 오브젝트가 비활성화되거나 파괴되면 코루틴은 중단된다.
[출처]
http://teddy.tistory.com/entry/코루틴의-이해] Teddy Games
'유니티 > 꿀팁ㅇㅇㅇ' 카테고리의 다른 글
가비지 컬렉션이란? (0) | 2018.04.26 |
---|---|
프레임 (0) | 2018.04.26 |
[이펙트] 텍스쳐 최적화 (1) | 2018.04.19 |
연습장. (0) | 2018.04.05 |
유용하게 쓰이는 Mathf 함수 (0) | 2018.03.27 |