IEnumerator AnimateCoroutine(float duration, System.Func <float, bool> update, EASING easing, System.Action onComplete = null)
    {
        AnimationCurve curve = this.linear;

        switch (easing)
        {
        case EASING.ELASTIC_IN:
            curve = this.elasticIn;
            break;

        case EASING.ELASTIC_OUT:
            curve = this.elasticOut;
            break;

        case EASING.EASE_IN:
            curve = this.easeIn;
            break;

        case EASING.EASE_OUT:
            curve = this.easeOut;
            break;

        case EASING.EASE_INOUT:
            curve = this.easeInOut;
            break;
        }

        update(0f);

        for (float time = 0f; time < duration; time += Time.deltaTime)
        {
            float t = time / duration;


            float t1 = curve.Evaluate(t);

            if (update.Invoke(t1))
            {
            }
            else
            {
                yield break;
            }
            yield return(null);
        }

        update(1f);

        onComplete?.Invoke();
    }
    private float ease(EASING mode)
    {
        float delta = mode == EASING.IN ? timeSinceFadeInTriggered : timeSinceFadeOutTriggered;

        return(Mathf.SmoothStep(0.0f, 1.0f, (1.0f / (fadeDuration - delta) - padding)));
    }
 public Coroutine Animate(float duration, System.Func <float, bool> update, EASING easing, System.Action onComplete = null)
 {
     return(StartCoroutine(AnimateCoroutine(duration, update, easing, onComplete)));
 }