코루틴 중단 현상

Noke·2025년 5월 21일

Unity TIL

목록 보기
15/31

유니티에서 갑자기 코루틴이 실행이 되지 않는 현상이 종종 발생한다.

그런데, 에디터에서 어떠한 오류도 나오지 않으면, 대체 무엇이 오류인지 정말 디버깅하기 힘들다고 생각한다.

그래서, 오늘은 내가 과제 개발을 하면서 발생한 이 문제에 대해서 다루어 볼 것이다.


📖 코루틴이란?

아래는 내가 과제에서 제작한 코드의 일부분이다.

public void SpeedBuff(float multiplier, float duration)
{
    StartCoroutine(CoSpeedBuff(multiplier, duration));
}

private IEnumerator CoSpeedBuff(float multiplier, float duration)
{
    speedMultiplier = multiplier;

    yield return new WaitForSeconds(duration);

    speedMultiplier = 1f;
}

코루틴은 위와 같이 IEnumerator로 정의된 메서드와 같은 형태를 띈다.

그러나, 일반 메서드처럼 사용할 수는 없고 StartCoroutine()을 통해서 코루틴을 실행할 수 있다.

또한, 코루틴을 만들 때는 꼭 yield return 혹은 yield break 값이 있어야 한다.

yield return : 일정 시간을 기다릴 때 사용, null을 붙이면 한 프레임을 기다린다.
yield break : 만나는 즉시 코루틴을 나간다.

예시로 위의 SpeedBuff() 메서드를 보면,

  • 외부에서 SpeedBuff() 메서드 실행
  • 메서드 내부에서 CoSpeedBuff() 코루틴 실행
  • 코루틴에서 스피드 배율 값을 바꿈
  • duration 시간 동안 기다림
  • 다시 기존의 스피드 배율 값으로 돌아옴

이런 식으로 실행된다고 생각하면 된다.


💢 코루틴 중단 현상

코루틴이 멈추었을 때, 정말 난감한 것이 바로 "왜 멈추었는가?"를 알 수가 없다는 점이다.

만약, 아래와 같은 코드가 있다고 하자.

public IEnumerator CoSpeedBuff(float multiplier, float duration)
{
    speedMultiplier = multiplier;
	Debug.Log("1");
    
    yield return new WaitForSeconds(duration);
	Debug.Log("2");
    
    speedMultiplier = 1f;
    Debug.Log("3");
}

이런 식으로 디버깅 코드를 작성해서 본다고 해도 1까지 출력이 되고 2부터는 갑자기 출력이 안 되는 현상을 많이 보았다.

오늘 그 이유에 대해서 알게 되었는데, 바로 코루틴을 시작한 게임 오브젝트가 비활성화 혹은 파괴되었을 때, 이러한 현상이 일어난다.


🔍 원인 분석

그렇다면, 왜 코루틴을 시작한 게임 오브젝트가 비활성화 혹은 파괴되었을 때 코루틴 중단 현상이 일어날까?

유니티에서 StartCoroutine()을 호출하면, 해당 MonoBehaviour 인스턴스에 코루틴이 등록되어 유니티의 프레임 루프 안에서 실행된다. 이때, yield return으로 일시 중단된 코루틴은 다음 프레임에 해당 인스턴스에서 다시 이어서 실행해줘야 한다.

그러나, 아래와 같은 경우 코루틴은 해당 인스턴스에서 코루틴이 동작하지 않게 된다.

SetActive(false) : MonoBehaviour는 Update, Coroutine, Invoke 등 모든 프레임 기반 동작을 수행하지 않음.
Destroy() : MonoBehaviour 자체가 메모리에서 사라지기 때문에 코루틴도 함께 정리됨.

그래서 코루틴이 일시 중단(yield)된 상태라면, 다시 이어질 기회 없이 중단된 상태처럼 보이게 된다.

코루틴이 yield return을 기준으로 멈추는 이유도, 이를 기준으로 실행 흐름이 일시 중단되며, 다음 프레임이나 조건에서 다시 이어지기 때문이다.


📢 결론

  • 코루틴은 MonoBehaviour에 귀속됨
  • yield return은 실행을 유니티에 위임하는 시점
  • 그 사이에 오브젝트가 꺼지거나 파괴되면, 유니티는 해당 코루틴을 다시 불러주지 않음

오늘은 코루틴 중단 현상에 대해 파헤쳐 보았다.

사실 이전 프로젝트에서도 이러한 현상이 빈번하게 발생했는데 그 이유를 알게되어 너무나도 속이 시원하다.

profile
유니티 개발자(진)

0개의 댓글