코루틴(Coroutine)이란?
– 유니티에서 비동기적인 작업을 처리할 때 활용하는 대표적인 기능이 코루틴이다.
Update()와 달리 코루틴은 특정 시간 간격이나 조건에 따라 실행 흐름을 분할 할 수 있어서
반복적인 동작이나 지연 처리가 필요할 때 매우 유용하다.
※ 비동기- 코루틴을 비동기라고 말은 했지만, 스레드 기반 비동기(멀티스레딩)과는 다르다.
메인 스레드 안에서 시분할처럼 실행 되는 형태이다.(협동형 멀티태스킹)
- 코루틴의 기본 사용 방법
코루틴을 사용하기 위해서는 아래 두가지가 필요하다.
- 반환 타입이 IEnumerator 여야 한다.
- yield return 구문을 통해 중단점을 지정해야한다.
예제- 코루틴을 이용한 일정 시간 간격으로 적 생성 처리
using System.Collections;
using UnityEngine;
public class EnemySpawner : MonoBehaviour {
public GameObject enemyPrefab;
public float spawnInterval = 3f;
void Start() {
StartCoroutine(SpawnEnemy()); //코루틴 시작
}
IEnumerator SpawnEnemy() {
while (true) {
Instantiate(enemyPrefab, transform.position, Quaternion.identity); //적 생성
yield return new WaitForSeconds(spawnInterval); //3초 대기
}
}
}
- IEnumerator: C#에서 반복자를 나타내는 인터페이스지만, 유니티에서는 Coroutine의 메서드 정의에 활용.
- yield return:
– yield return null: 다음 프레임까지 대기 후 이어서 실행
– yield return new WaitForSeconds(2f): 2초 대기
– yield return someFunction(): 다른 코루틴이 완료될 때까지 대기
- StartCoroutine() StopCoroutine()
using System.Collections;
using UnityEngine;
public class EnemySpawner : MonoBehaviour {
public GameObject enemyPrefab;
public float spawnInterval = 3f;
public Coroutine spawnCoroutine; //코루틴 변수
void Start() {
spawnCoroutine = StartCoroutine(SpawnEnemy()); //코루틴 시작 및 spawnCoroutine 할당
}
IEnumerator SpawnEnemy() {
while (true) {
Instantiate(enemyPrefab, transform.position, Quaternion.identity); //적 생성
yield return new WaitForSeconds(spawnInterval); //3초 대기
}
}
public void OnClick() {
StopCoroutine(spawnCoroutine); //실행중인 spawnCoroutine 코루틴 중단
}
}
– StopCoroutine()으로 특정 코루틴을 중단 할 수도 있으며,
– StopAllCoroutines()으로 해당 오브젝트에서 실행 중인 모든 코루틴을 중지 하는 것도 가능하다.
- 다양한 활용 예시
- 조건이 충족될 때 까지 대기
bool isCheck = false;
IEnumerator WaitUntilCouroutine() {
yield return new WaitUntil(() => isCheck); //isCheck가 true일 때까지 대기
Debug.Log("isCheck는 true!");
}
- 네트워크 요청 시 처리
IEnumerator GetDataFromServer(string url) {
UnityWebRequest request = UnityWebRequest.Get(url);
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.Success)
{
Debug.Log("요청 성공!: " + request.downloadHandler.text);
}
else
{
Debug.LogError("요청 실패!: " + request.error);
}
}
- 코루틴 사용시 주의 사항
- MonoBehaviour에서만 사용 가능
– StartCoroutine() 및 StopCoroutine()은 MonoBehaviour를 상속받은 클래스에서만 실행 할 수 있다. - 코루틴 중첩 호출 및 While()문 사용 설계
– 종료 시점을 어떻게 할지 설계 해두는 편이 좋다. yield break; 을 사용하게 되면 해당 코루틴을 종료한다. - 코루틴과 Update() 혼동 주의
– Update()는 매 프레임마다 호출 되며, 코루틴은 내가 정의한 흐름에 따라 진행하기 때문에,
적절히 구분해서 사용해야 한다. - 성능 관리
– 코루틴 자체는 가볍지만, 과도하게 많은 코루틴을 생성하면 오버헤드가 발생할 수 있다.
유니티 코루틴은 게임내에서 대기나 반복이 필요한 로직을 명확하게 구성하는데 도움을 준다.
비동기 흐름의 복잡성을 간단하게 표현해주기 때문에,
프로젝트 규모가 커지더라도 많은 부분에서 유용하게 쓸 수 있다.
기본 사용법 예시만 들었지만, 다음 포스팅에는 코루틴 성능에 대해서 조금 적어 볼 계획이다.
lBdpYTMv KgROhfdF PRpRBzuG