Unity C# 코루틴 -> IEnumerator.Next()로 리팩토링

2022.12.07 - [Unity/프로그래밍] - Unity C# IEnumerator vs IEnumerable

 

Unity C# IEnumerator vs IEnumerable

본론에 앞서 IEnumerator 에 대한 이야기부터 해보자. IEnumerator는 유니티를 다루는 사람이라면 코루틴 덕분에 익숙한 키워드 일 것이다. 코루틴 앞에 붙여야 하는 자료형으로 의미를 모르고 외웠을

mentum.tistory.com

이전 글에 이어서 구체적인 IEnumerator 예시를 살펴보자.

 

 

#. 구현 사항

다음과 같은 코드를 짜고 있었다.

 

게임 중 특정 이벤트에 대한 보상을 정의한다.

기획자가 엑셀에서 임의 개수의 보상 타입과 value를 쭉 적으면, 그걸 파싱 해서 타입-Value 리스트 형태로 만들어놓고,

순차적으로 보상을 적용&지급한다.

 

각 보상의 결과는 타입별로 각각의 팝업 노출하며, 팝업 하나를 닫을 때마다 순차적으로 다음 팝업을 표기한다.

팝업이 존재하지 않는 경우도 있다.

 

#. 어떻게 구현할까?

지급과 팝업 연출은 시점을 다르게 가져가는 경우가 많으니 이 부분은 제쳐놓고,

보상 팝업이 순차적으로 표기되어야 하는 부분이 문제다.

우선 이벤트 Queue방식의 구현을 해도 되고 팝업 노출 자체는 순차적으로 꺼내서 처리하면 될 것이다.

 

순서대로 팝업을 열기위해서는 동시에 노출하는 게 아니라 콜백을 통해 다음 팝업이 노출될 수 있도록 관리해야할 것이다. 다음과 같은 구현이 필요할 것이다.

void OpenPopup(Reward result, Action callback)
{
    if( /* result가지고 무언가 테스트 */ )
    {
        // 팝업이 있으면 콜백을 다시 팝업한테 넘겨서 확인버튼누르면 콜백호출되게함
    }
    else
    {
        callback.Invoke();
    }
}

 

 

#. (유니티 환경) 코루틴

코루틴으로 짠다면 일반적으로 다음과 같은 코드가 나올 것이다.

bool isCanNext = false;

void StartReward(List<Reward> rewardList)
{
    StartCoroutine(RewardCoroutine(rewardList));
}

IEnumerator RewardCoroutine(List<Reward> rewardList)
{
    foreach (Reward result in rewardList)
    {
        isCanNext = false;
        OpenPopup(result, SetCanNext);
        yield return new WaitUntil(() => isCanNext);
    }
    
    // 보상처리 종료
}

private void SetCanNext()
{
    isCanNext = true;
}

딱히 문제없이 잘 돌아간다.

 

 

#. IEnumerator 구현

isCanNext라는 플래그 변수를 없애고 IEnumerator로 구현해본다면 다음과 같이 만들어 볼 수 있다.

IEnumerator enumerator;

void StartReward(List<Reward> rewardList)
{
    Debug.Log("보상처리시작");
    enumerator = rewardList.GetEnumerator();
    CallNext();
}

private void CallNext()
{
    Debug.Log("CallNext");
    if(enumerator.MoveNext())
    {
        OpenPopup(enumerator.Current, CallNext);
    }
    else
    {
        Debug.Log("보상처리종료");
    }
}

IEnumeratorMoveNext()는 다음 열거가 있는지를 체크해주기 때문에

false를 리턴한다면 모든 열거가 끝났다는 걸 의미한다. 

 

오히려 코드가 더 간소해진 것을 확인할 수 있다.

 

IEnumerator는 이외에도 대화 시스템 같이 무언가를 연속적으로 보여줘야 하는 경우에 유용하게 사용할 수 있다.

코루틴의 '반환 값이 없다'라는 특성 때문에 대신 제네릭 IEnumerator을 사용하는 것은 때때로 더 간편하고 명료한 듯하다.

 

 

 

댓글

Designed by JB FACTORY