코루틴은 Unity에서 비동기 작업을 처리할 때 유용한 기능입니다. 게임 개발 중 특정 시간 간격을 두고 연속 작업을 처리하거나, 애니메이션, 대기 시간 등을 추가하는 데 자주 사용됩니다. 이번 글에서는 코루틴의 기본 사용법, 중요 함수, 예시를 통해 코루틴의 사용법을 자세히 설명합니다.
1. 코루틴이란?
Unity에서 코루틴(Coroutine)은 특정 조건이나 시간 동안 코드의 실행을 일시 정지했다가 다시 실행할 수 있는 함수입니다. IEnumerator 타입을 반환하며, yield 키워드를 사용해 특정 조건이 만족될 때까지 대기하거나, 다음 프레임에서 다시 실행되도록 설정할 수 있습니다.
코루틴의 가장 큰 장점은 프레임의 흐름을 멈추지 않으면서도 반복적으로 실행 가능한 작업을 수행할 수 있다는 것입니다. 예를 들어, 일정 시간 간격으로 적이 생성되거나, 캐릭터의 점프 애니메이션이 자연스럽게 연출되도록 하는 데 유용합니다.
2. 코루틴 기본 사용법
코루틴을 작성하려면 IEnumerator 타입의 메서드를 정의하고, yield return 구문을 사용하여 작업을 대기시키는 방식으로 구현합니다.
IEnumerator ExampleCoroutine()
{
Debug.Log("코루틴 시작");
yield return new WaitForSeconds(2); // 2초 대기
Debug.Log("2초 후 실행");
}
코루틴을 시작하려면 StartCoroutine() 함수를 사용합니다.
void Start()
{
StartCoroutine(ExampleCoroutine());
}
위 코드를 실행하면 "코루틴 시작"이 출력된 후 2초 동안 대기하고 "2초 후 실행"이 출력됩니다.
3. 코루틴의 주요 함수
코루틴에서 자주 사용하는 대기 함수들을 정리하였습니다. 이 함수들은 코루틴 내에서 사용되어 특정 조건을 만족할 때까지 대기하는 역할을 합니다.
3.1. yield return null
다음 프레임까지 대기한 후 코루틴의 다음 줄을 실행합니다. 매 프레임마다 실행하고 싶은 작업이 있을 때 유용합니다.
IEnumerator Example()
{
while (true)
{
Debug.Log("매 프레임 실행");
yield return null; // 다음 프레임까지 대기
}
}
3.2. yield return new WaitForSeconds(float seconds)
특정 시간 동안 대기한 후 다음 작업을 실행합니다. WaitForSeconds는 게임 시간을 기준으로 대기하며, 게임의 FPS와 상관없이 정확한 시간 대기를 제공합니다.
IEnumerator TimerCoroutine()
{
Debug.Log("5초 대기 시작");
yield return new WaitForSeconds(5f); // 5초 대기
Debug.Log("5초 경과 후 실행");
}
3.3. yield return new WaitForEndOfFrame
프레임이 끝날 때까지 대기합니다. 주로 화면에 마지막으로 렌더링되는 프레임 이후에 수행할 작업이 있을 때 유용합니다.
IEnumerator AfterRenderCoroutine()
{
yield return new WaitForEndOfFrame();
Debug.Log("프레임 렌더링 완료 후 실행");
}
3.4. yield return new WaitUntil(Func<bool> predicate)
특정 조건이 참이 될 때까지 대기한 후 다음 작업을 실행합니다. 조건을 함수로 넘기면, 해당 조건이 만족될 때까지 코루틴이 반복 대기합니다.
IEnumerator WaitUntilExample()
{
yield return new WaitUntil(() => Input.GetKeyDown(KeyCode.Space));
Debug.Log("스페이스바 입력됨");
}
3.5. yield return new WaitWhile(Func<bool> predicate)
특정 조건이 거짓이 될 때까지 대기한 후 다음 작업을 실행합니다. WaitWhile은 대기 조건을 부정하는 조건문으로 설정합니다.
IEnumerator WaitWhileExample()
{
yield return new WaitWhile(() => Time.time < 10);
Debug.Log("10초 경과 후 실행");
}
4. 코루틴의 정지와 재개
코루틴을 중단하거나 재시작하는 상황도 자주 발생합니다. 코루틴을 종료하고 싶을 때는 StopCoroutine() 또는 StopAllCoroutines()을 사용할 수 있습니다.
- StopCoroutine(): 특정 코루틴을 정지합니다.
- StopAllCoroutines(): 모든 코루틴을 정지합니다.
IEnumerator MoveCoroutine()
{
while (true)
{
transform.Translate(Vector3.forward * Time.deltaTime);
yield return null;
}
}
void Start()
{
StartCoroutine(MoveCoroutine());
}
void StopMovement()
{
StopCoroutine("MoveCoroutine"); // MoveCoroutine 정지
}
5. 코루틴 활용 예제
5.1. 적 생성기
적을 일정 간격으로 생성하는 간단한 예제입니다.
public GameObject enemyPrefab;
public Transform spawnPoint;
IEnumerator SpawnEnemies()
{
while (true)
{
Instantiate(enemyPrefab, spawnPoint.position, spawnPoint.rotation);
yield return new WaitForSeconds(3); // 3초마다 적 생성
}
}
void Start()
{
StartCoroutine(SpawnEnemies());
}
5.2. 스킬 충전 애니메이션
스킬 사용 후 다시 사용할 수 있을 때까지 차징 애니메이션을 실행하는 예제입니다.
public float chargeTime = 5f;
public GameObject skillIndicator;
IEnumerator ChargeSkill()
{
skillIndicator.SetActive(true); // 충전 표시
yield return new WaitForSeconds(chargeTime); // 차징 시간 동안 대기
skillIndicator.SetActive(false); // 차징 완료 후 표시 제거
}
void UseSkill()
{
StartCoroutine(ChargeSkill());
}
5.3. 화면 깜빡임 효과
피격 시 화면을 깜빡이게 하는 효과를 코루틴으로 구현할 수 있습니다.
public GameObject screenOverlay;
IEnumerator FlashScreen()
{
screenOverlay.SetActive(true);
yield return new WaitForSeconds(0.1f); // 0.1초 깜빡임
screenOverlay.SetActive(false);
}
void OnHit()
{
StartCoroutine(FlashScreen());
}
6. 코루틴 사용 시 주의할 점
- 오래 지속되는 코루틴 관리: 무한 루프(while(true))로 실행되는 코루틴은 메모리와 성능에 영향을 줄 수 있습니다. 필요하지 않을 때는 반드시 StopCoroutine()을 호출하여 종료하세요.
- 코루틴이 종료되지 않는 상황: yield return 문 없이 while 루프를 사용할 경우, Unity가 멈출 수 있습니다. 코루틴 내부에서는 항상 yield return을 통해 대기 상태로 전환해 주어야 합니다.
- 메모리 관리: 코루틴은 비동기적으로 실행되기 때문에, 여러 코루틴이 동시에 실행되면 메모리에 부담이 될 수 있습니다. 필요 없는 코루틴은 종료하거나 관리해야 합니다.
코루틴은 Unity에서 비동기 작업을 쉽게 처리할 수 있는 강력한 도구입니다. 타이밍을 조절하거나, 조건에 따라 반복 작업을 실행할 때 코루틴을 적절히 사용하면 코드의 가독성과 효율성이 크게 향상되니 잘 사용해봅시다~!!~!!~
'Unity' 카테고리의 다른 글
[Unity] 유니티에서 Text를 쓸 때 주의해야할 점! TextMeshPro (0) | 2024.11.07 |
---|---|
[Unity] 3D에서 UI를 만들 때 꼭 알아야하는 필수 컴포넌트 RectTransform! (1) | 2024.11.07 |
[Unity] Scale의 비밀 부모-자식 관계의 스케일 상속은 각 계층에서 곱셈 방식으로 적용 (0) | 2024.11.06 |
[Unity] 유니티에서 물리 관련 함수를 FixedUpdate()문에 쓰는 이유 (0) | 2024.11.06 |
[Unity] 기본 호출 함수의 생명주기 Start() vs Awake() (0) | 2024.11.06 |