본문 바로가기
Unity

유니티 Coroutin 에서 continue 를 쓸 때 주의할 점

by Oz Driver 2025. 3. 12.

유니티에서 코루틴을 사용할 때 continue 와 yield return 의 차이를 이해하는 것은 매우 중요합니다. 특히 while (true) 같은 무한 루프를 사용할 때, continue 만 사용하면 예상치 못한 성능 저하가 발생할 수 있습니다.

 

아래와 같은 코드를 살펴보겠습니다.

private IEnumerator SpawnColumn()
{
    WaitForSeconds wait = new(GameData.PipeSpawnTime);

    while (true)
    {
        if (!GameManager.Instance.IsGameActive)
            continue;

        Instantiate(pipesPrefab, transform.position, Quaternion.identity);
        transform.position = new Vector3.Zero;

        yield return wait;
    }
}

 

Game 이 활성화 된 상태에서는 정해진 시간마다 instance 를  생성하는 하고, 비활성 상태로 접어들면, instance 생성을 잠시 멈추려는 의도의 코드입니다.

그러나 continue 만 사용하면 yield return wait 를 만나지 못하게 되므로, while - continue 가 무한으로 반복되고, yield return 이 실행되지 않기 때문에 유니티에게 제어권을 주지 않아 프레임을 처리할 시간을 주지 않고, 결과적으로 CPU가 과부하 상태에 빠질 수 있게 됩니다.

이 문제를 해결하려면 continue;를 사용하기 전에 yield return null 을 추가해야 합니다.

private IEnumerator SpawnColumn()
{
    WaitForSeconds wait = new(GameData.PipeSpawnTime);

    while (true)
    {
        if (!GameManager.Instance.IsGameActive)
        {
            yield return null;
            continue;
        }

        Instantiate(pipesPrefab, transform.position, Quaternion.identity);
        transform.position = new Vector3.Zero;
        yield return wait;
    }
}

 

이렇게 수정하면 IsGameActive 가 false일 때, yield return null 이 실행되어 한 프레임을 쉬고 다시 while (true) 를 실행하게 됩니다. 따라서 CPU 가 과부하 상태에 빠지는 것을 방지하고, 게임이 다시 활성화되었을 때 자연스럽게 이어질 수 있게 됩니다.

 

코루틴은 유니티에서 매우 강력한 기능이지만, 잘못 사용하면 성능 문제가 발생할 수 있습니다.

continue 만 사용하면 코루틴이 유니티의 프레임 처리를 방해할 수 있으므로, 반드시 yield return을 사용하여 제어권을 넘겨줘야 합니다.

 

그리고 아래의 코드처럼 continue 대신 while 문으로 계속 대기를 시키게 만들 수도 있습니다. 

IEnumerator SpawnColumn()
{        
    WaitForSeconds wait = new (GameData.PipeSpawnTime);

    while (true)
    {
        while(!GameManager.Instance.IsGameActive)
            yield return null;
        
        float height = Random.Range(GameData.PipeMinHeight, GameData.PipeMaxHeight);

        Instantiate(pipesPrefab, transform.position, Quaternion.identity);
        transform.position = new Vector3.Zeor;

        yield return wait;
    }
}