Version: 2019.3
게임 오브젝트 생성 및 제거
네임스페이스

코루틴

함수를 호출하면 값을 반환하기 전에 실행 완료됩니다. 이는 함수에서 수행되는 모든 액션이 하나의 프레임 업데이트 내에서 발생해야 한다는 것을 의미합니다. 시간이 지남에 따라 절차식 애니메이션이나 일련의 이벤트를 포함하는 데 함수 호출을 사용할 수 없습니다. 예를 들어 오브젝트의 알파(불투명도) 값이 완전히 보이지 않을 때까지 점진적으로 감소시키는 작업을 고려해야 합니다.

void Fade() 
{
    for (float ft = 1f; ft >= 0; ft -= 0.1f) 
    {
        Color c = renderer.material.color;
        c.a = ft;
        renderer.material.color = c;
    }
}

그대로 Fade 함수는 기대했던 효과를 내지 못합니다. 페이딩이 보이기 위해서는 중간 값이 렌더링 중임을 나타내기 위해 프레임 시퀀스에 대해 알파를 줄여야 합니다. 그러나 이 함수는 하나의 프레임 업데이트 내에서 전체적으로 실행됩니다. 중간 값은 절대로 보이지 않으며 개체는 즉시 사라집니다.

프레임 단위로 페이드를 실행하는 코드를 Update 함수에 추가하여 이런 상황을 처리할 수 ​​있습니다. 하지만 이러한 종류의 작업에 코루틴(coroutine)을 사용하는 것이 더 편리합니다.

코루틴은 실행을 일시 중지하고 Unity에 제어 권한을 반환한 후 다음 프레임에서 중단했던 위치에서 계속할 수 있는 함수와 같습니다. C#에서는 코루틴이 다음과 같이 선언됩니다.

IEnumerator Fade() 
{
    for (float ft = 1f; ft >= 0; ft -= 0.1f) 
    {
        Color c = renderer.material.color;
        c.a = ft;
        renderer.material.color = c;
        yield return null;
    }
}

즉, 이것은 IEnumerator 반환 타입과 바디 어딘가에 포함된 yield 반환문으로 선언된 함수입니다. yield return null 라인은 실행이 일시 중지되고 다음 프레임에서 다시 시작되는 지점입니다. 코루틴을 실행하려면 StartCoroutine 함수를 사용해야 합니다.

void Update()
{
    if (Input.GetKeyDown("f")) 
    {
        StartCoroutine("Fade");
    }
}

Fade 함수의 루프 카운터는 코루틴의 수명 동안 올바른 값을 유지합니다. 실제로 모든 변수 또는 파라미터는 yield 간에 올바르게 보존됩니다.

기본적으로 코루틴은 프레임이 생성된 후 다시 시작되지만 WaitForSeconds를 사용하여 시간 지연을 도입할 수도 있습니다.

IEnumerator Fade() 
{
    for (float ft = 1f; ft >= 0; ft -= 0.1f) 
    {
        Color c = renderer.material.color;
        c.a = ft;
        renderer.material.color = c;
        yield return new WaitForSeconds(.1f);
    }
}

이것은 한동안 효과를 전파하는 방법으로 사용될 수 있지만 유용한 최적화이기도 합니다. 게임에서 많은 작업을 주기적으로 수행해야 하며 이를 수행하는 가장 확실한 방법은 Update 함수에 작업을 포함시키는 것입니다. 하지만 이 함수는 일반적으로 초당 여러 번 호출됩니다. 작업을 자주 반복할 필요가 없는 경우 코루틴에 넣을 수 있습니다. 예를 들어 적이 근처에 있을 경우 플레이어에게 경고하는 경보가 있을 수 있습니다. 코드는 다음과 같이 표시될 수 있습니다.

function ProximityCheck() 
{
    for (int i = 0; i < enemies.Length; i++)
    {
        if (Vector3.Distance(transform.position, enemies[i].transform.position) < dangerDistance) {
                return true;
        }
    }
    
    return false;
}

적이 많은 경우 이 함수를 모든 프레임에 호출하면 상당한 오버헤드가 발생할 수 있습니다. 하지만 코루틴을 사용하여 10분의 1초마다 호출할 수 있습니다.

IEnumerator DoCheck() 
{
    for(;;) 
    {
        ProximityCheck();
        yield return new WaitForSeconds(.1f);
    }
}

이렇게 하면 게임플레이에 눈에 띄는 영향 없이 수행되는 검사 수를 크게 줄일 수 있습니다.

참고: StopCoroutineStopAllCoroutines를 사용하여 코루틴을 중지할 수 있습니다. 또한 SetActive(false)로 인해 연결된 게임 오브젝트가 비활성화될 때에도 코루틴이 중지됩니다. Destroy(example)(여기서 example은 MonoBehaviour 인스턴스)을 호출하면 OnDisable이 즉시 트리거되고 코루틴이 처리되므로 효과적으로 중지할 수 있습니다. 마지막으로 OnDestroy는 프레임이 끝날 때 호출됩니다.

MonoBehaviour 인스턴스에서 enabled를 false로 설정하여 MonoBehaviour를 비활성화한 경우에는 코루틴이 중지되지 않습니다.

게임 오브젝트 생성 및 제거
네임스페이스