GameDevelop/Unity팀프로젝트

[TeamProject1_2025.04.10] 코루틴(Coroutine), Invoke

도도돋치 2025. 4. 10. 21:23
Contents 접기
728x90

기본 개념 

팀원분의 코드를 보다가 IEnumerator을 보게되어 여쭤봤는데, 코루틴(Coroutine)이라고 하셨다.

어떨때 쓰는지와 어떻게 쓰는지에 관해 관련 개념을 찾아보았다.

 

🔹찾아보니 코루틴은 어떤 느낌인가? 라고물으면 아래와 같이 정리할 수 있었다.

"함수를 실행하다가 잠깐 멈췄다가, 다시 돌아와서 계속 실행하는 것"

 

유니티 코루틴(Coroutine)이란? 

- 코루틴은 시간과 관련된 처리를 깔끔하게 할 수 있게 도와주는 기능
- 쉽게 말하면 중간에 잠깐 멈췄다가 다시 실행할 수 있는 함수
- 일반 함수랑 다른 점은 실행 도중에 yield return이라는 키워드로 잠깐 멈췄다가 다시 돌아올 수 있음
- 게임 개발을 하다 보면 어떤 동작을 바로 실행하는 게 아니라, 잠깐 기다렸다가 실행하거나 천천히 실행해야 할 때가 있는데,
이럴 때 사용하는 유니티 기능이 바로 코루틴(Coroutine) 이다.

 

왜 필요한가?

유니티에서 Update() 같은 일반 함수는 한 프레임 안에 다 끝나야 하지만,
게임에서는 이런 상황이 자주 발생한다.

3초 후 보스 등장
총알 발사 → 0.5초 대기 → 다시 발사
캐릭터 천천히 사라짐
몇 초 간격으로 반복 실행


이런 걸 전부 Update로 처리하면 코드가 복잡하고 보기 힘들어지고, 이때 코루틴을 사용하면 코드가 깔끔해진다.

 

  • 내가 실행시킨 딱 그 코루틴만 멈출 수 있음
  • 함수 이름이랑 관계없이 안전하게 멈춤
  • 여러 개 코루틴 돌릴 때 구분 가능

 

코루틴 사용 방법

1. IEnumerator 함수 만들기

public IEnumerator PlayCardShuffle()
{
    while(GameManager.instance.isPlaying)
    {
        yield return new WaitForSeconds(6f);	// 6초 대기

        StartCoroutine(shuffleCardPlaceAnimation.Play());
    }
}

 

2. StartCoroutine()으로 실행

StartCoroutine(PlayCardShuffle());

 

3. StopCorutine()으로 멈춤

 

1) 코루틴 이름 기억해서 멈추기(추천)

private Coroutine changeProfileCoroutine = null; // 프로필 변경 Coroutine

changeProfileCoroutine = StartCoroutine(ChangeProfile()); // 코루틴 실행 & 변수에 넣기

StopCoroutine(changeProfileCoroutine); // 변수에 넣어둔 코루틴 멈추기

 

📝 예시

Coroutine myCoroutine;

void Start()
{
    myCoroutine = StartCoroutine(SpawnBoss());
}

void Update()
{
    if (Input.GetKeyDown(KeyCode.Space))
    {
        StopCoroutine(myCoroutine);  // 실행중인 코루틴 멈춤
    }
}

IEnumerator SpawnBoss()
{
    while (true)
    {
        Debug.Log("보스 스폰 준비중");
        yield return new WaitForSeconds(1f);
    }
}

 

2) 코루틴 함수 이름으로 바로 멈추기

StartCoroutine("SpawnBoss");

StopCoroutine("SpawnBoss");

→ 이렇게 문자열로 넣어서 바로 멈출 수도 있음.
근데 이 방법은 오타 위험이나, 어떤 파라미터로 실행했는지 모를 때가 있어서 잘 안 쓴다.

또한 파라미터 들어가는 것은 문자열 방식 못씀

 

이번 프로젝트에 적용된 예시

이번 프로젝트에 적용된 코루틴 예시인데, 보면 profileChangeInter에 값이 안들어가있는데 WaitForSeconds를 사용해서 중간에 잠깐 멈추는 것을 볼수 있다. 이 profileChangeInter값은 어디서 확인할 수 있을까?

[SerializeField] private float profileChangeInterval; // 프로필이 변경되는 시간
private Coroutine changeProfileCoroutine = null; // 프로필 변경 Coroutine


private IEnumerator ChangeProfile()
{
    int i = 0;
    while (true)
    {
        if (i == names.Length)
        {
            i = 0;
            if (!touchButton.gameObject.activeSelf) ActiveTouchButton(true);
        }

        yield return new WaitForSeconds(profileChangeInterval); // n초마다 변경

        profile.SetProfile(i, names[i]);
        i++;
    }
}

public void GoToMainMenu()
{
    // 실행 중인 코루틴이 있으면 정지
    if (changeProfileCoroutine != null)
    {
        StopCoroutine(changeProfileCoroutine);
    }
    //SceneManager.LoadScene("MainScene");

    GameManager.instance.SetNewStageSetting();
}

 

 바로 해당 Script가 붙어있는 오브젝트에서 profileChangeInter를 입력할 수 있다.

 

자주 쓰이는 yield 종류

yield 종류 설명
yield return null 1프레임 대기
yield return new WaitForSeconds(x) x초 대기
yield return new WaitUntil(()=>조건) 조건이 true 될 때까지 대기
yield return new WaitForEndOfFrame() 프레임 끝날 때까지 대기

 


 

Coroutine vs Invoke

이전에 Invoke를 들었었는데, 이것도 딜레이를 준다고 들었었다.

하지만 실무에서 많이 안쓴다고 해서 코루틴과 어떤차이가 있길래 많이 안쓰는지 정리해보았다.

 

구분 Coroutine Invoke
기능 코드 잠깐 멈췄다가 다시 실행 일정 시간 후 함수 1번 실행
여러번 반복 가능 InvokeRepeating() 써야 가능
멈추기 StopCoroutine() CancelInvoke()
파라미터 전달 가능 가능
자유도 높음 낮음

 

쉽게말하면?
  • Coroutine → 일시정지 + 반복 + 제어
  • Invoke → 그냥 타이머 느낌

 

📝 예시비교

 

🔹Coroutine

StartCoroutine(ChangeProfile());

→ 계속 바꾸거나 복잡한 처리 가능
→ 언제든 멈출 수 있음

 

🔹Invoke

Invoke("ChangeProfile", 3f);

→ 3초 후에 ChangeProfile 함수 딱 1번 실행
→ 반복하려면 InvokeRepeating 써야함

 Invoke로 오류 예시

[ Invoke는 시간이 지나면 오브젝트가 없어도 무조건 실행하려고한다. ]

방 안에 내가 있다.
5초 후에 내가 문을 열기로 예약했다. (Invoke)
근데 그 5초 안에 내가 방에서 사라졌다. (Destroy)
그럼 5초 후에?
문 열 사람 자체가 없음 → 에러 (NullReferenceException)

 

📌핵심

 

  • Invoke는 시간 지나면 무조건 실행하려고 함
  • 근데 실행할 대상(GameObject)이 사라졌으면 → 에러
  • 그래서 Unity에서는 오브젝트 파괴될 가능성 있으면 Invoke 잘 안씀

📌반면 코루틴은?

  • 코루틴은 내가 사라지면 자동으로 멈춤
  • 코루틴은 MonoBehaviour에 붙어있어서 그 오브젝트 없으면 알아서 종료됨

 

 

 

📖 정리

  • 코루틴은 특정 동작을 잠깐 멈췄다가 다시 실행할 수 있게 해주는 기능
  • 유니티에서는 IEnumerator 함수 + yield return 으로 사용
  • 주로 시간 지연, 반복, 애니메이션, 효과 처리할 때 많이 씀
  • 실행은 StartCoroutine(함수)
  • 멈출 땐 StopCoroutine(변수) 또는 StopCoroutine("함수이름")
  • 여러 개 코루틴 돌리거나 파라미터 있을 땐 변수 방식 사용하는게 좋다
728x90