기본 개념
팀원분의 코드를 보다가 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("함수이름")
- 여러 개 코루틴 돌리거나 파라미터 있을 땐 변수 방식 사용하는게 좋다
'GameDevelop > Unity팀프로젝트' 카테고리의 다른 글
[TeamProject2_2025.05.11] 프로젝트 기획, 우리팀 규칙 (0) | 2025.05.11 |
---|---|
[TeamProject1_2025.04.11] 카드 게임 - 팀프로젝트 회고 (0) | 2025.04.11 |
[TeamProject1_2025.04.09] SoundManager, AudioSource, AudioClip (0) | 2025.04.09 |
[TeamProject1_2025.04.08] 카드게임제작 - 카드뒤집기, 애니메이션 기능 (1) | 2025.04.08 |
[TeamProject1_2025.04.07] 팀 협업 도구 Notion, GitHub (1) | 2025.04.08 |