Unity 코루틴(Coroutine)으로 딜레이 구현하기
게임을 만들다보면 딜레이가 필요하다.
시전 모션이 끝나면 공격이 들어간다던지, 물리적인 판정 자체에 몇 프레임 씩 딜레이를 넣을수도 있다.
그러기 위해서 보통 코루틴을 사용한다.
인보크를 쓰면 안되나요? 라고 물어볼 수 있는데, 인보크 대신 코루틴을 사용하는 이유는 다음 게시글에 잘 정리되어 있다.
기본 형태
IEnumerator FunctionWithDelay()
{
yield return null;
// 딜레이 뒤로 원하는 기능을 작성
Debug.Log("1프레임 있다가 호출!");
}
StartCoroutine(FunctionWithDelay);
다음과 같은 방식으로 선언한다.
반환값으로 반드시 IEnumerator
를 해줘야한다.
호출은 StartCoroutine()
을 이용한다.
yield return null은 함수 실행이 종료되었다가 1프레임 뒤에 바로 종료지점 다음부터 실행을 다시 시작한다.
해당 yield return을 여러 방식으로 바꿔서 다양한 종류의 딜레이를 구현할 수 있다.
물리 프레임으로 딜레이 주기
yield return null
은
Update의 실행이 끝날 때마다 진입을 시작하는데,
그렇기 때문에 정확히 1프레임 뒤에 실행이 되는 것이다.
반대로 yield return new WaitForFixedUpdate()
를 하게 되면
FixedUpdate가 끝날 때마다 진입을 한다.
즉, 물리 프레임으로 1만큼 뒤에 실행이 되는 것이다.
참고로 위 방법대로 하면 yield return
을 할 때마다 new
를 호출하기 때문에
약간의 성능 저하가 있을 수 있다.
때문에 해당 딜레이를 사용하기 위해선 new WaitForFixedUpdate()
를 미리 호출해두어 저장해주자.
_wait = new WaitForFixedUpdate();
IEnumerator FunctionWithDelay()
{
yield return _wait;
// 딜레이 뒤로 원하는 기능을 작성
Debug.Log("1 물리 프레임 있다가 호출!");
}
추가로 Update와 FixedUpdate의 구조가 어떻게 다른지 알고 싶다면 다음 글을 참고하자.
시간으로 딜레이 주기
new WaitForSeconds(seconds)
와 new WaitForSecondsRealtime(seconds)
를 사용할 수 있다.
WaitForSeconds(seconds)
는 게임 시간 기준으로 입력값만큼의 초를 기다렸다가 진입하고,
WaitForSecondsRealtime(seconds)
는 현실 시간 기준으로 기다린다.
둘이 다를 수가 있나요?라고 물어볼 수 있는데,
Time Scale
이 1이 아니면 둘의 시간이 서로 달라진다.
이에 대해서 위에 링크해놓은 글의 0. Time Scale 부분을 참고하자.
_wait = new WaitForSeconds(5f);
IEnumerator FunctionWithDelay()
{
yield return _wait;
// 딜레이 뒤로 원하는 기능을 작성
Debug.Log("5초 있다가 호출!");
}
그 외의 다양한 딜레이들
new WaitForEndOfFrame()
: 한 프레임의 화면 렌더링 작업이 끝나면 진입
startCoroutiune(string)
: 입력한 이름의 코루틴이 끝나면 진입
yield return new www(string)
: 해당 웹 통신 작업이 끝나면 진입
코루틴을 통해 게임 동작에 딜레이를 부여하고 시간이나 프레임 경과에 따른 상태 변화들을 부여할 수 있도록 하자.
Uploaded by N2T