본문 바로가기
Utils

유니티, 코루틴 최적화(Coroutine Yield Instruction)

by Client. DJ 2021. 12. 23.
반응형

매번 생성된는 반복기 타이밍

코루틴의 경우 잦은 new() 생성, 메모리 할당으로 인해 불필요한 메모리를 차지합니다.

private IEnumerator CountDown(int startTime)
{
    while (true)
    {
        timerText.text = (startTime--).ToString();
        yield return new WaitForSeconds(1f);
        if (startTime <= 0) break;
    }
}

위와 같이 yield return new WaitForSeconds(1f) 호출을 반복적으로 진행합니다. 이러한 경우는 불필요한 생성이 반복이 됩니다. 스크립트 작성 간 유니티에서는 많은 코루틴을 사용하게 되고, 다른 GameObject에서도 같은 yield를 호출을 하는 경우가 많습니다.

문제점 해결 (스크립트 생성)

YieldInstructionCache.cs

using System.Collections.Generic;
using UnityEngine;

public static class YieldInstructionCache
{
    public static readonly WaitForEndOfFrame WaitForEndOfFrame = new WaitForEndOfFrame();
    public static readonly WaitForFixedUpdate WaitForFixedUpdate = new WaitForFixedUpdate();
    private static readonly Dictionary<float, WaitForSeconds> waitForSeconds = new Dictionary<float, WaitForSeconds>();

    public static WaitForSeconds WaitForSeconds(float seconds)
    {
        WaitForSeconds wfs;
        if (!waitForSeconds.TryGetValue(seconds, out wfs))
            waitForSeconds.Add(seconds, wfs = new WaitForSeconds(seconds));
        return wfs;
    }
}

이러한 경우는 캐싱을 하여 사용하면 되고, 글로벌하게 관리를 해줄 스크립트를 작성해줍니다.

예제

위와 같이 캐싱을 할 수 있는 영역을 만들고, 아래와 같이 전역 클래스 함수를 사용 합니다.

private IEnumerator CountDown(int startTime)
{
    while (true)
    {
        timerText.text = (startTime--).ToString();
        yield return YieldInstructionCache.WaitForSeconds(1f);
        if (startTime <= 0) break;
    }
}

YieldInstructionCache.WaitForSeconds(1f)호출로 캐싱을 해주었기에 반복적인 호출에도 새로 할당하지 않고 사용을 할 수 있습니다.

 

반응형

댓글