게임 오브젝트 생성 및 삭제
특수 폴더와 스크립트 컴파일 순서

코루틴(Coroutine)

함수를 호출하면 반환값을 반환하기 전에 실행 완료됩니다. 즉, 함수에서 수행되는 작업은 하나의 프레임에서 수행된다는 것을 의미하고, 함수 호출은 절차적 애니메이션을 포함하거나 시간의 경과와 함께 일련의 이벤트에는 사용할 수 없습니다. 예를 들어, 오브젝트의 알파(투명도)가 완전히 투명해질 때까지 서서히 계속 감소하는 장면을 상정했다고 합시다.

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

위의 상태에서 Fade 함수가 원하는대로 효과를 얻을 수 없습니다. Fade가 시각적으로 알 수 있게 하기 위해서 알파는 몇 프레임에 걸쳐 렌더링되는 중간값으로 변경 한 후 점점 감소할 필요가 있습니다. 그러나 위의 함수는 하나의 프레임에서만 실행됩니다. 중간값은 시각적으로 알 수 없고, 오브젝트는 순간적으로 투명해집니다.

Update 함수에 코드를 추가하는 것도 프레임마다 페이드 할 수 있습니다. 그러나 이러한 작업은 보통 코루틴을 사용하면 편리합니다.

코루틴은 실행을 중지하여 Unity에 제어권을 돌려주고, 그러나 계속할 때는 다음 프레임에서 중지한 곳부터 실행을 계속할 수 있는 기능입니다. C#에서 코루틴은 다음과 같이 선언합니다:

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

즉, 이것은 IEnumerator 형식을 반환값으로 가지며 yield return 구문을 어디엔가 포함하고 있는 함수입니다. yield return 행은 실행을 중지하고 다음 프레임에서 실행을 재개할 수 있는 지점입니다. 코루틴을 실행하려면 StartCoroutine 함수를 사용합니다. \n

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

UnityScript에서는 좀 더 간단합니다. yield statement를 포함하는 함수는 코루틴으로 해석되어 IEnumerator 반환 형식은 명시적으로 선언될 필요가 없습니다:

function Fade() {
    for (var f = 1.0; f >= 0; f -= 0.1) {
        var c = renderer.material.color;
        c.a = f;
        renderer.material.color = c;
        yield;
    }
}

또한 UnityScript에서 코루틴을 시작하는 경우, 일반 함수와 동일하게 호출합니다:

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

Fade 함수의 루프 카운터는 코루틴의 라이프 사이클을 통해 올바른 값을 유지합니다. yield 중에 모든 변수 또는 파라미터가 올바르게 보존됩니다.

기본적으로 코루틴은 yield 한 직후의 프레임에서 재개되지만, 지연했다가 다시 시작하려면 WaitForSeconds 함수를 사용합니다:

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

UnityScript에서는:

function Fade() {
    for (var f = 1.0; f >= 0; f -= 0.1) {
        var c = renderer.material.color;
        c.a = f;
        renderer.material.color = c;
        yield WaitForSeconds(0.1);
    }
}

이 방법으로 효과를 일정한 시간 범위에서 펼칠 수 있지만, 최적화 방법으로 해도 편리합니다. 게임 중의 태스크는 정기적으로 수행해야 하며, 간단한 방법은 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;
}

적이 많은 경우에 이 함수를 매 프레임 호출하여 현저한 오버 헤드를 초래할 지도 모릅니다. 그러나 코루틴을 사용하여 1/10 초 간격으로 호출할 수 있습니다:

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

따라서 게임에 악영향을 주지 않고 체크 횟수를 비약적으로 감소시킬 수 있습니다.

게임 오브젝트 생성 및 삭제
특수 폴더와 스크립트 컴파일 순서