Quick Reference
| 필요 | yield 또는 API | 결과 |
|---|---|---|
| 다음 렌더 프레임까지 대기 | yield return null | 다음 프레임에서 이어집니다. |
| 게임 시간으로 대기 | new WaitForSeconds(seconds) | timeScale = 0이면 진행하지 않습니다. |
| 실제 시간으로 대기 | new WaitForSecondsRealtime(seconds) | pause 중에도 진행합니다. |
| 조건이 충족될 때까지 대기 | WaitUntil, WaitWhile | predicate를 매 프레임 평가합니다. |
| 한 번만 실행해야 하는 연출 | 반환된 Coroutine 저장 후 StopCoroutine(handle) | 이전 실행을 끊고 새 실행만 남깁니다. |
코루틴은 여러 프레임에 걸친 순차 흐름입니다. 스레드를 만들지 않으며 yield 이전의 무거운 작업은 그대로 메인 스레드를 막습니다. WaitForSeconds는 호출한 그 순간부터 정확히 초를 재는 타이머가 아닙니다. 현재 프레임 끝에서 대기를 시작하고, 시간이 지난 첫 다음 프레임에 재개하므로 긴 프레임만큼 늦어질 수 있습니다.
private Coroutine _flashHandle;
private void OnHit()
{
if (_flashHandle != null) StopCoroutine(_flashHandle);
_flashHandle = StartCoroutine(FlashDamage());
}
private IEnumerator FlashDamage()
{
indicator.SetActive(true);
yield return new WaitForSeconds(0.15f);
indicator.SetActive(false);
_flashHandle = null;
}대기와 수명
GameObject와 Behaviour는 다릅니다
| 변경 | OnDisable | 해당 코루틴 | 다시 켤 때 |
|---|---|---|---|
behaviour.enabled = false | 호출됨 | 자동 중단되지 않음 | 기존 코루틴이 계속 진행할 수 있습니다. |
gameObject.SetActive(false) | 활성 컴포넌트에 호출됨 | 중단됨 | 자동 재개하지 않으므로 필요하면 다시 시작합니다. |
Destroy(gameObject) | 비활성화·파괴 수명주기가 진행됨 | 중단됨 | 새 인스턴스가 필요합니다. |
| 씬 unload | 해당 오브젝트가 unload되면 수명 종료 | 중단됨 | DontDestroyOnLoad 여부를 따로 봅니다. |
MonoBehaviour 체크박스만 꺼서 화면 갱신을 멈춘 경우에는 코루틴이 남을 수 있습니다. 활성 수명과 코루틴 수명을 묶으려면 OnDisable에서 명시적으로 중단하고 handle을 null로 비웁니다. SetActive(false)에서는 자동 중단되더라도 handle을 비워야 재활성화 뒤에 오래된 handle을 살아 있는 작업으로 오해하지 않습니다.
private void OnDisable()
{
if (_flashHandle == null) return;
StopCoroutine(_flashHandle);
_flashHandle = null;
}중단 API를 섞지 않기
StartCoroutine(IEnumerator)로 시작했다면 반환된 Coroutine handle을 보관해 같은 방식으로 중단하는 편이 가장 읽기 쉽습니다. 문자열 overload는 이름 기반으로 중단할 때만 쓰며 런타임 오타와 추가 오버헤드가 있습니다. 서로 다른 overload나 새로 만든 IEnumerator를 섞어 중단 대상을 추측하지 마세요.
매 프레임 상태를 계속 관측해야 하는 체력 바·추적 카메라는 Update가 더 직접적입니다. 파일 I/O나 네트워크처럼 실제 비동기 완료를 기다리는 일은 코루틴만으로 백그라운드가 되지 않으므로 API의 Task/Unity async API와 취소 정책을 따릅니다.
자주 틀리는 부분
| 증상 | 원인 | 처리 |
|---|---|---|
| pause에서 연출이 멈춤 | WaitForSeconds가 scaled 시간입니다. | WaitForSecondsRealtime 또는 unscaled 시간 루프를 고릅니다. |
| 같은 깜빡임이 겹침 | 매 요청마다 새 코루틴을 시작했습니다. | handle을 저장하고 기존 작업을 중단합니다. |
| 스크립트를 껐는데 효과가 계속 바뀜 | enabled = false가 코루틴을 자동 중단하지 않습니다. | OnDisable에서 명시적으로 수명을 정리합니다. |
| 지정한 초보다 늦게 재개 | frame end부터 대기하고 프레임 경계에서만 재개합니다. | 정확한 wall-clock deadline이 필요하면 시간을 직접 비교합니다. |
코루틴을 중단하면 그 흐름의 정리 코드가 실행될 것이라고 가정하지 마세요. 화면 상태, 입력 잠금, 임시 오브젝트처럼 반드시 되돌려야 하는 것은 중단 경로에서도 명시적으로 복구합니다.
참고 링크
4 sources