본문 바로가기

Unity/팁

[Unity 유니티] Coroutine 코루틴 yield return 최적화

private IEnumerator Example()
{
    yield return new WaitForSeconds(1f);
}

코루틴을 사용할 때 new WaitForSeconds()를 이용하면 실행될 때마다 가바지 값이 생긴다.

이를 막기 위해서는 미리 캐싱을 해두고 사용하면 된다.

private IEnumerator Example()
    {
    	WaitForSeconds wait = new WaitForSeconds(1f);
    	yield return wait;
    }

하지만 작업을 하다보면 여러번 사용하는 경우가 생기고,

더 편하고 효율적인 작업을 위해서 코루틴 매니저를 만들면, 미리 캐싱된 값을 수정하면서 사용할 수 있다.

 

< 코루틴 매니저 >

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

static class YieldCache
{
    class FloatComparer : IEqualityComparer<float>
    {
        bool IEqualityComparer<float>.Equals(float x, float y)
        {
            return x == y;
        }
        int IEqualityComparer<float>.GetHashCode(float obj)
        {
            return obj.GetHashCode();
        }
    }

    public static readonly WaitForEndOfFrame WaitForEndOfFrame = new WaitForEndOfFrame();
    public static readonly WaitForFixedUpdate WaitForFixedUpdate = new WaitForFixedUpdate();

    private static readonly Dictionary<float, WaitForSeconds> _timeInterval = new Dictionary<float, WaitForSeconds>(new FloatComparer());
    private static readonly Dictionary<float, WaitForSecondsRealtime> _timeIntervalReal = new Dictionary<float, WaitForSecondsRealtime>(new FloatComparer());

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

    public static WaitForSecondsRealtime WaitForSecondsRealTime(float seconds)
    {
        WaitForSecondsRealtime wfsReal;
        if (!_timeIntervalReal.TryGetValue(seconds, out wfsReal))
            _timeIntervalReal.Add(seconds, wfsReal = new WaitForSecondsRealtime(seconds));
        return wfsReal;
    }
}

< 코루틴 매니저 사용법 >

private IEnumerator Example()
{
    yield return YieldCache.WaitForSeconds(1f);
}