public void SetGameSpeed(GameSpeedCommand newGameSpeed)
    {
        StopGameSpeedTransition();

        if (!gameSpeedModifiers.Contains(newGameSpeed))
        {
            gameSpeedModifiers.Add(newGameSpeed);
        }

        gameSpeedRoutine = GameSpeedTransition(newGameSpeed);
        StartCoroutine(gameSpeedRoutine);

        OnSpeedTransitionDone += DisposeGameSpeedCommand;
    }
    private IEnumerator GameSpeedTransition(GameSpeedCommand gsc)
    {
        currentGameSpeed = Time.timeScale;

        if (gsc.InCurve == null)
        {
            gsc.InCurve = Curves.Instance.SmoothOut;
        }
        if (gsc.OutCurve == null)
        {
            gsc.OutCurve = Curves.Instance.SmoothOut;
        }

        // Transition in
        for (float t = 0f; t < 1f; t += Time.unscaledDeltaTime / gsc.InTransitionTime)
        {
            float value = gsc.InCurve.Evaluate(t);
            Time.timeScale = Mathf.Lerp(currentGameSpeed, GetTargetGameSpeed(), value);
            yield return(null);
        }
        Time.timeScale   = GetTargetGameSpeed();
        currentGameSpeed = Time.timeScale;

        // Hold
        for (float h = 0f; h < 1f; h += Time.unscaledDeltaTime / gsc.HoldTime)
        {
            yield return(null);
        }

        // Transition out
        for (float t = 0f; t < 1f; t += Time.unscaledDeltaTime / gsc.OutTransitionTime)
        {
            float value = gsc.InCurve.Evaluate(t);
            Time.timeScale = Mathf.Lerp(currentGameSpeed, GetTargetGameSpeed(), value);
            yield return(null);
        }
        Time.timeScale   = GetTargetGameSpeed();
        currentGameSpeed = Time.timeScale;

        if (OnSpeedTransitionDone != null)
        {
            OnSpeedTransitionDone(gsc);
        }
    }
    public void SetGameSpeed(int callerID,
                             float multiplier,
                             float inTransitionTime  = 0.1f,
                             float outTransitionTime = 0.3f,
                             float holdTime          = 0.3f,
                             AnimationCurve inCurve  = default(AnimationCurve),
                             AnimationCurve outCurve = default(AnimationCurve)
                             )
    {
        GameSpeedCommand newGameSpeed = new GameSpeedCommand()
        {
            instanceID        = callerID,
            NewGameSpeed      = Mathf.Clamp01(multiplier),
            InTransitionTime  = inTransitionTime,
            OutTransitionTime = outTransitionTime,
            HoldTime          = holdTime,
            InCurve           = inCurve,
            OutCurve          = outCurve
        };

        SetGameSpeed(newGameSpeed);
    }
 private void DisposeGameSpeedCommand(GameSpeedCommand gsc)
 {
     ReleaseGameSpeed(gsc.instanceID);
 }