Powerup Timer not Working

I cannot figure out how to make my timer work! If the player collides with the slowdown powerup (slowing all objects on the screen) the slowdown continues forever even though I have a timer setup. Do I have the timer in the wrong spot in Update? Does this have something to do with how I have variables setup and Time.timescale? I have looked on unity answers, youtube, and google for days, but there is nothing. This cannot be that difficult and I am so close! This is driving me crazy!

Here is my code:

Code 1:

using UnityEngine;
using System.Collections;

public class PowerUpManager : MonoBehaviour {

	private  bool doublePoints;
	private  bool slowMo;
	private  bool fastMo;

	private  bool powerUpActive;
	private float powerUpLengthCounter;

	private ScoreManager theScoreManager;

	private float score;

	private float slowDown = Time.timeScale ;
	//private float slowDown = Time.unscaledDeltaTime ;



	// Use this for initialization
	void Start () {
		theScoreManager = FindObjectOfType <ScoreManager > ();
	}
	
	// Update is called once per frame
	void Update () {

		if (powerUpActive) {

			powerUpLengthCounter -= Time.deltaTime;

			if (slowMo) {

				//Time.unscaledDeltaTime = slowDown;
				Time.timeScale = slowDown;
				slowDown  = 0.5f;

				
			}
		}

		if (powerUpLengthCounter <= 0) {

			//Time.unscaledDeltaTime = slowDown;
			Time.timeScale = slowDown;
			slowDown = 1f;
			powerUpActive = false;

		}
	
	}

	public void ActivatePowerUpSlowMotion(bool slow, float time, float effect){

		slowMo = slow;
		powerUpLengthCounter = time ;
		slowDown = effect;

		powerUpActive = true;

	}
} 

Code 2:

using UnityEngine;
using System.Collections;

public class PowerUp : MonoBehaviour {

	public bool doublePoints;
	public bool slow;
	public bool fast;
	public float speed=Time .timeScale ;

	public float powerUpLength;

	private PowerUpManager thePowerUpManager;

	// Use this for initialization
	void Start () {
		thePowerUpManager = FindObjectOfType <PowerUpManager > ();
	}
	
	// Update is called once per frame
	void Update () {
	
	}

	void OnTriggerEnter2D(Collider2D other){

		if (other.tag == "Player") {
			thePowerUpManager.ActivatePowerUpSlowMotion (slow, powerUpLength,speed ); 
		}

		gameObject.SetActive (false);
		Destroy(gameObject);
	}
}

Have you tried using a coroutine like this? (Untested)

public void ActivatePowerUpSlowMotion(float time, float speed)
	{
		StartCoroutine (SlowMoRoutine (time, speed));
	}

	IEnumerator SlowMoRoutine(float time, float speed)
	{
		float duration = time * speed; //Convert the powerup duration to realtime, since WaitForSeconds uses gametime. My math may be off here.
		Time.timeScale = speed;
		yield return new WaitForSeconds (duration);
		Time.timeScale = 1f;
	}

The only downside to this is that there’s no way to stop the powerup prematurely. If you don’t need to do that this code should work fine.

After having a quick read, both methods you tried involves either deltaTime or WaitForSeconds(). Both rely on the time scale. Effectively your timer slows down too. You can either scale the wait duration with the time scale so it takes the right amount of time still or use a timer not affected by time scale. i.e. Time.unscaledTime.

Hope this helps.

Hi there, I think Time.realtimeSinceStartup would have the effect you want. It is not affected by Time.deltaTime. Here’s a link to its documentation if you wanna read more on it.

I believe something like the following should work (or at least set you on the right track):

private float powerUpStartingTime;

void Update ()
{
    if (powerUpActive)
    {
        //calculate how much time has passed since the powerup was activated
        float timePassed = Time.realtimeSinceStartup - powerUpStartingTime;

        //if that amount of time is equal to, or bigger than
        //the power up duration, deactivate the power up
        if(timePassed >= powerUpLengthCounter)
        {
            Time.timeScale = 1;
            powerUpActive = false;
        }
    }
}

public void ActivatePowerUpSlowMotion(float time, float effect)
{
    //activate the power up
    powerUpActive = true;

    //get the duration of the power up
    powerUpLengthCounter = time;

    //apply the desired time slow amount
    Time.timeScale = effect;

    //save time of power up activation
    powerUpStartingTime = Time.realtimeSinceStartup;
}