SetActive(false) 전후의 코루틴 흐름을 단순화한 SVG 도식입니다. 실제 Profiler 캡처가 아닙니다.
SetActive(false) 전후의 코루틴 흐름을 단순화한 SVG 도식입니다. 실제 Profiler 캡처가 아닙니다.

SetActive(false)는 코루틴까지 끊습니다

코루틴은 별도 스레드가 아닙니다. MonoBehaviour가 붙은 GameObject에 SetActive(false)를 호출하거나 스크립트를 Destroy하면 실행이 멈춥니다. 반대로 컴포넌트의 enabled만 false로 바꾸는 것으로는 코루틴이 자동 중단되지 않습니다. 이 차이를 놓치면 페이드, 타이머, 네트워크 요청 완료를 기다리는 흐름이 조용히 사라진 것처럼 보입니다.

using System.Collections;
using UnityEngine;

public class FadeController : MonoBehaviour
{
    [SerializeField] private CanvasGroup target;

    public void Begin()
    {
        StartCoroutine(FadeOut());
    }

    private IEnumerator FadeOut()
    {
        while (target.alpha > 0f)
        {
            target.alpha = Mathf.MoveTowards(target.alpha, 0f, Time.deltaTime);
            yield return null;
        }
    }
}

계속 살아 있어야 할 일을 분리합니다

화면을 숨기려고 컨트롤러 전체를 끄고 있다면, 코루틴을 실행하는 오브젝트와 숨길 오브젝트를 나누는 편이 낫습니다. FadeController는 켜 둔 채 CanvasGroup이나 자식 UI만 꺼 보세요. 정말 중단할 때는 Coroutine 핸들을 저장하고 명시적으로 취소하세요.

이 OnDisable은 Unity가 자동으로 코루틴을 멈추는 규칙이 아니라 이 컴포넌트가 선택한 명시적 취소 정책입니다. enabled=false 뒤에도 작업을 유지해야 한다면 넣으면 안 됩니다.

private Coroutine running;

public void Begin()
{
    if (running != null)
        StopCoroutine(running);

    running = StartCoroutine(FadeOutTracked());
}

private IEnumerator FadeOutTracked()
{
    yield return FadeOut();
    running = null;
}

private void OnDisable()
{
    if (running == null)
        return;

    StopCoroutine(running);
    running = null;
}

코루틴을 스레드로 착각하지 않습니다

코루틴 안에서 파일 읽기나 무거운 계산을 해도 메인 스레드에서 실행됩니다. 프레임을 나누는 데는 좋지만 CPU 시간을 다른 코어로 보내 주지는 않습니다. 무거운 작업이라면 Profiler로 먼저 시간을 확인하고 Job System이나 async/await가 맞는지 따로 판단하세요.

검증 범위

공식 문서 대조

검증일

Unity 6 공식 문서와 코드 경로를 대조했습니다. 별도 Unity 프로젝트에서 직접 재현한 결과는 아닙니다.

확인한 공식 문서Unity 코루틴 매뉴얼 ↗