static public void CancelInvoke(IPauseable target, PausableInvokeCallback callback)
    {
        if (target != null)
        {
            List <PausableInvokeRoutine> targetInvokes = _invokes[target] as List <PausableInvokeRoutine>;

            if (targetInvokes != null)
            {
                bool found = false;

                foreach (PausableInvokeRoutine routine in targetInvokes)
                {
                    if (routine.callback == callback)
                    {
                        _instance.StopCoroutine(routine.coroutine);
                        found = true;
                    }
                }

                if (found)
                {
                    RemoveInvoke(target, callback);
                }
            }
        }
    }
    private IEnumerator _Invoke(IPauseable target, PausableInvokeCallback callback, float delay)
    {
        float elapsed = -Mathf.Epsilon;

        while (elapsed < delay)
        {
            if (!target.IsPaused())
            {
                elapsed += Time.deltaTime;
            }
            yield return(null);
        }

        callback();
        RemoveInvoke(target, callback);
    }
    static public void Invoke(IPauseable target, PausableInvokeCallback callback, float delay)
    {
        if (target != null)
        {
            Coroutine coroutine = _instance.StartCoroutine(_instance._Invoke(target, callback, delay));

            List <PausableInvokeRoutine> targetInvokes = _invokes[target] as List <PausableInvokeRoutine>;
            if (targetInvokes == null)
            {
                targetInvokes = new List <PausableInvokeRoutine>();
            }

            PausableInvokeRoutine routine;
            routine.callback  = callback;
            routine.coroutine = coroutine;

            targetInvokes.Add(routine);

            _invokes[target] = targetInvokes;
        }
    }
    static private void RemoveInvoke(IPauseable target, PausableInvokeCallback callback)
    {
        if (target != null)
        {
            List <PausableInvokeRoutine> targetInvokes = _invokes[target] as List <PausableInvokeRoutine>;

            if (targetInvokes != null)
            {
                List <PausableInvokeRoutine> newList = new List <PausableInvokeRoutine>(targetInvokes);

                foreach (PausableInvokeRoutine routine in targetInvokes)
                {
                    if (routine.callback == callback)
                    {
                        newList.Remove(routine);
                    }
                }

                targetInvokes.Clear();
                targetInvokes = newList;
            }
        }
    }