코루틴(Coroutine)
1. 어디에 쓰이는가?
우선, 코루틴이 어떤 상황에서 필요한지 알아보자.
유니티에서 특정 코드가 반복적으로 실행되기 위해서는 Update문에 코드를 작성하면 되는데,
간혹 Update가 아닌 곳에서도 반복적으로 코드가 실행되어야할 필요가 있을 때가 있다.
이럴 때 코루틴을 사용하는 것이 매우 효과적이다.
또한, 업데이트문을 사용하면 원하든 원하지 않든 업데이트문이 매 프레임마다 계속 반복적으로 실행되지만,
코루틴을 사용한다면 자신이 필요한 순간에만 반복하고 필요하지 않을 때에는 전혀 사용하지 않음으로써 자원관리를 매우 효과적으로 할 수 있다.
그 밖에도 당장 실행되는게 아니라 일정 시간동안 멈춰있다가 그 뒤에 동작하게 하거나 특정 조건을 부여해서 코드가 실행되도록 할 수도 있다.
사용법도 간단하면서 다양하게 활용이 가능하기 때문에,
코루틴은 실무에서 굉장히 빈번하게 사용되므로 꼭 자세히 알아둘 필요가 있다.
2. 코루틴 작성 방법
코루틴의 사용 방법을 알아보자.
크게 2가지의 필수조건이 있다.
1. 코루틴은 IEnumerator라는 반환형으로 시작해야한다.
2. yield retrun이 반드시 함수 내부에 존재해야한다.
결과적으로 코루틴은 이런 모양이 된다.
IEnumerator 함수이름()
{
yield return // + 조건
// 함수 내용
}
주석을 확인해보면, yield return 뒤에 +조건이라고 쓰여있는데, 해당 조건 입력되는 코드에 따라서 코루틴의 동작을 다양하게 컨트롤 할 수 있다.
- yield return 의 종류
1. yield return null; : 다음 프레임에 실행 됨.
2. yield return new WaitForSeconds( float ); : 매개변수로 입력한 숫자에 해당하는 초만 큼 기다렸다가 실행됨.
3. yield return new WaitForSecondsRealtime( flaot ); : 매개변수로 입력한 숫자에 해당하는 초만큼 기다렸다가 실행됨.
4. 그외 : yield return + new WaitForFixedUpdate / WaitForEndOfFrame 등...
5. yield break;
yield return의 종류는 꽤나 다양한데 위에서 소개한 것들 중 1번이나 2번을 거의 많이 쓰고 나머지는 필요에 따라서 찾아 쓰면 된다.
2번과 3번이 무슨 차이인지 궁금할 수 있는데,
3번은 현실의 시간을 기준으로 체크하는 것이고, 2번은 유니티상에서의 시간을 기준으로 체크하는 것이다.
유니티에서 시간은 TimeScale을 사용해서 느리게하거나 빠르게 조절할 수 있는데, 이 값의 변화에 영향을 받는 것이 2번이고 무관한 것이 3번이다.
그리고 5번의 yield break;는 딱 보면 알겠지만 코루틴을 끝내버리는 코드이다.
일정 조건을 만족했을 때 코루틴이 끝나길 원한다면 해당 코드를 작성해주면 된다.
따라서 자신에게 필요한 조건을 작성해주고 그 후에 동작될 코드를 적어주면 코루틴이 완성된다.
아래와 같이 작성해주면, 2초뒤에 hp를 10깍아버리는 HpAttack이라는 코루틴 메소드가 완성되었다.
IEnumerator HpAttack()
{
yield return new WaitForSeconds( 2.0f );
Hp -= 10;
}
만약 해당 코루틴 내부에 for문이나 while문을 사용해준다면 마치 업데이트문 처럼 매 프레임마다 반복되게 할 수 있다.
Update문은 따로 동작하면서도 말이다.
만약, 업데이트문에 이런 반복문을 쓰게 되면 해당 반복이 끝날 때까지, 반복문 아래에 있는 코드들은 전혀 실행이 되지 않는다.
그러나 코루틴에서 반복문을 사용하면 Update와는 별도로 동작하기 때문에 모든 스크립트가 정상적으로 동작하게 된다.
3. 코루틴 사용 방법
이렇게 코루틴 함수를 생성했는데 어떻게 사용해야하는걸까?
그냥 일반 메소드들 처럼 단순하게 이름을 사용해서 쓸 수는 없다. 코루틴은 특별하기 때문에.
StartCoroutine( ); 을 사용해서 쓸 수 있다. ( ) 안에다가 매개변수를 넣는 것처럼 생성한 코루틴 이름을 적어주면 된다.
위에서 예로 만들었던 HpAttack( ) 코루틴을 사용하려면 다음과 같이 작성하면 된다.
StartCoroutine(HpAttack());
StartCoroutine("HpAttack");
이렇게 2가지 방법으로 사용할 수 있다.
4. Invoke보다 뛰어난 장점
일정 시간 만큼 지연시켰다가 코드를 동작하게 한다는 점에서 Invoke와 동일한 기능을 가지고 있지만,
코루틴에만 있는 훌륭한 장점이 있다.
앞서 말했듯이, 코루틴을 통해서 Update문과는 별개로 동작하는 또다른 서브루틴을 만들 수 있기도 하지만,
그것 말고도 매개변수를 넘길 수 있다는 장점이 있다.
코루틴은 앞에 IEnumerator를 작성한다는 것 말고는 일반적인 메소드와 동일하기 때문에 매개변수를 사용할 수 있다.
따라서 굉장히 자유롭게 코루틴을 쓸 수 있다.
그렇다면, 매개변수가 존재하는 코루틴을 쓸때는 어떻게 호출을 해야하는지 알아보자.
우선 StartCoroutine으로 호출하는 것을 동일하고, 마찬가지로 2가지 방식으로 매개변수를 전달 할 수 있다.
StartCoroutine( 메소드이름( 매개변수1, 매개변수2 ) );
StartCoroutine( "메소드이름", 매개변수 );
문자열로 메소드 이름을 적어서 코루틴을 동작시킬 경우 ,를 찍어서 매개변수를 전달할 수 있다.
다만 이 경우에는 매개변수가 1개까지만 전달할 수 있다.
반면, 일반적인 메소드를 호출하는 것처럼 적어준다면 여러개의 매개변수를 전달 할 수 있다.
따라서 되도록이면 첫번째 방식으로 코루틴을 호출하여 사용하도록 하자.
성능적인 면에서도 첫번째 방법이 더 좋다.
5. 결론
이렇게 코루틴에 대해서 알아보았다.
사실 상 Invoke로 할 수 있는 것들은 코루틴으로 전부 다 할 수 있다.
인보크가 간단하긴 하지만 코루틴이 상당히 우수하므로 특별한 경우가 아니라면 되도록 코루틴으로 사용하도록 하자.
'유니티 Unity > 유니티 기능 구현' 카테고리의 다른 글
[유니티] 비디오플레이어로 UI에서 동영상 재생하기 (1) | 2022.01.06 |
---|---|
[유니티] 서버(인터넷)에서 이미지 가져와서 사용하는 방법 (0) | 2022.01.04 |
[유니티] 리지드바디(Rigidbody) 스크립팅 (0) | 2021.09.11 |
[유니티] Rigidbody(리지드바디)로 플레이어 움직임 구현하기 - 1 (0) | 2021.09.10 |
[유니티] Rigidbody(리지드바디) 기본 속성 값 파악하기 (0) | 2021.09.09 |
댓글