- Home /
Timer Progress Bar
I have a powerup timer and wanted to add a progress bar that decreases at the same pace as the timer. I am very close to perfecting it, but the progress bar's fill decreases a few seconds before the timer runs out. I have tried several things, but cannot get it to work. Any suggestions?
Here's my code:
using UnityEngine;
using System.Collections;
using UnityEngine .UI;
using UnityEngine .SceneManagement ;
public class PowerUpTimer : MonoBehaviour {
public Text timer;
public Color slowDownColor;
public Color goldToothColor;
public Color X2Color;
float goldToothTimeAmt;
float multiplierTimeAmt;
float slowDownTimeAmt;
public Image goldToothFillImg;
public Image multiplierFillImg;
public Image slowDownFillImg;
// Use this for initialization
void Start () {
goldToothFillImg.enabled = false;
multiplierFillImg.enabled = false;
slowDownFillImg.enabled = false;
/*goldToothTimeAmt = GoldToothPowerUp .time ;
multiplierTimeAmt = Multiplier.time;
slowDownTimeAmt = TimeChangingPowerUp.time;*/
timer.GetComponent <Text> ();
timer.enabled = false;
}
// Update is called once per frame
void Update () {
if (Multiplier.Active == true) {
multiplierFillImg.enabled = true;
timer.enabled = true;
Multiplier.time -= Time.deltaTime;
multiplierFillImg.fillAmount -= (Time.deltaTime / (Multiplier.time));
//multiplierFillImg.fillAmount -= (Multiplier.time/Time.deltaTime);
timer.text = Multiplier.time.ToString ("f0");
timer.color = X2Color;
}
if (Multiplier.time <= 0) {
multiplierFillImg .enabled = false;
Multiplier.Active = false;
Multiplier.time = 20f;
timer.enabled = false;
}
if (GoldToothPowerUp .Active == true) {
goldToothFillImg.enabled = true;
timer.enabled = true;
GoldToothPowerUp .time -= Time.deltaTime;
goldToothFillImg.fillAmount -= (Time.deltaTime / (GoldToothPowerUp.time));
//goldToothFillImg.fillAmount -= (GoldToothPowerUp.time/Time.deltaTime);
timer.text = GoldToothPowerUp .time.ToString ("f0");
timer.color = goldToothColor ;
}
if (GoldToothPowerUp .time <= 0) {
goldToothFillImg.enabled = false;
GoldToothPowerUp.Active = false;
GoldToothPowerUp.time = 10f;
timer.enabled = false;
}
if (TimeChangingPowerUp .Active == true) {
slowDownFillImg.enabled = true;
timer.enabled = true;
TimeChangingPowerUp.time -= (Time.deltaTime/TimeChangingPowerUp.speed) ;
slowDownFillImg.fillAmount -= ((Time.deltaTime / TimeChangingPowerUp.speed) / (TimeChangingPowerUp.time));
//slowDownFillImg.fillAmount -= (TimeChangingPowerUp.time/Time.deltaTime);
timer.text = TimeChangingPowerUp.time .ToString ("f0");
timer.color = slowDownColor ;
}
if (TimeChangingPowerUp.time <= 0) {
slowDownFillImg.enabled = false;
TimeChangingPowerUp.Active = false;
TimeChangingPowerUp.time = 20f;
timer.enabled = false;
}
}
}
Have you tried using unity's built in Slider?
http://docs.unity3d.com/$$anonymous$$anual/script-Slider.html
Have you tried looking at $$anonymous$$athf.Lerp? Something like the below:
if ($$anonymous$$ultiplier.Active == true) {
multiplierFillImg.enabled = true;
timer.enabled = true;
$$anonymous$$ultiplier.time -= Time.deltaTime;
multiplierFillImg.fillAmount = $$anonymous$$athf.Lerp(0, 1, $$anonymous$$ultiplier.time);
timer.text = $$anonymous$$ultiplier.time.ToString ("f0");
timer.color = X2Color; }
I appreciate the help! I tried using what you suggested, but your current code causes the bar to be a solid circle with no movement. I also tried $$anonymous$$athf.Lerp(1, 0, $$anonymous$$ultiplier.time), but the bar was not visible. Does it have something to do with setting $$anonymous$$ultiplier.time -=Time.deltaTime? I don't know why this is so difficult to achieve?
This is the closest I've come (swapping out your line of code for this line of code) -
multiplierFillImg.fillAmount -= 1.0f / $$anonymous$$ultiplier.time * (Time.deltaTime*0.6f);
I am manually adjusting Time.deltaTime to make the load bar move slower, but this is ugly!
Well I was making a bunch of assumptions about your code, so I'm sure that has something to do with it. $$anonymous$$athf.Lerp() takes 3 parameters. A "Start" value, an "end" value, and "where we are right now" as a percentage of the difference between the two.
So it shows up as a full bar in the first case, because $$anonymous$$ultiplier.time is probably greater than 1, so Lerp is just returning the "end" value. Which is also why the bar is gone when you swap the 0 and the 1.
What you need to do is put the "start" value where I have 0, the "end" value where I have 1. Then you can manipulate whatever variable you have which describes the amount of time remaining on the power up to be a value between 0 and 1, and pass that into Lerp.
Answer by Habitablaba · Jun 24, 2016 at 08:55 PM
you have to define max time outside of the update function. It should not change each frame. Like... it should be the total amount of time you want the power up to be active for each time. In this case, it looks like you are trying to set it to 20. So let's go with that.
Next, you need to find how much time this power up has been active. Call that activeTime, for argument's sake. Each frame, you should be adding Time.deltaTime to that.
Now we need to know what percentage of the max time we've gone through so far. You do this by dividing activeTime by maxTime.
Finally, we need to use Lerp to give us a number between 0 and 1 that we can shove into fillAmount.
Below is a super quick, super basic version of what I'm saying. obviously you can rename the variables whatever you want, and there is obviously more to the method than what I have here, but this should get you a value that goes from 1 down to 0 as the power up remains active.
public float MaxTime = 20f;
public float ActiveTime = 0f;
public void Update()
{
ActiveTime += Time.deltaTime;
var percent = ActiveTime / MaxTime;
slowDownFillImg.fillAmount = Mathf.Lerp(0, 1, percent);
}
Thank you so much for your patience! Almost there! The fill rate now matches the timer rate, but the fill only works one time. When another powerup is obtained I see the timer, but no fill bar. I tried incorporating something into my code to fix this, but i could not get it to work:
if ($$anonymous$$ultiplier.Active == true) {
multiplierFillImg.enabled = true;
activeTime += Time.deltaTime;
var percent = activeTime / multiplier$$anonymous$$axTime;
multiplierFillImg.fillAmount = $$anonymous$$athf.Lerp (1,0,percent);
timer.enabled = true;
$$anonymous$$ultiplier.time -= Time.deltaTime;
timer.text = $$anonymous$$ultiplier.time.ToString ("f0");
timer.color = X2Color;
}
if ($$anonymous$$ultiplier.time <= 0) {
multiplierFillImg .enabled = false;
multiplierFillImg.fillAmount = 1;
$$anonymous$$ultiplier.Active = false;
$$anonymous$$ultiplier.time = 20f;
timer.enabled = false;
}
be sure to set activeTime = 0 when you are resetting all of your other variables. You should also consider having an activeTime variable for each power up. Otherwise, you won't be able to have multiple power ups active at the same time.
IT WOR$$anonymous$$S PERFECTLY!! Thank you again!
No problem, friend! Just glad we got there in the end ;)
Answer by srylain · Jun 22, 2016 at 04:30 AM
Instead of decreasing the fill amount every frame, just set the amount to the percentage of how much it should be filled. Something like:
float maxFillAmount;
float maxTime;
float remainingTime;
float percentageRemaining = remainingTime / maxTime;
float fillAmount = maxFillAmount * percentageRemaining;
slowDownFillImg.fillAmount = fillAmount;
That might work? It's basically what I did for my stuff.
How about:
slowDownFillImg.fillAmount = doneTime / maxTime;
Haven't used fillAmount before, but if it just uses a 0-1 value then that would be fine. I guess my way would work with stretching something along an axis.
Indeed, fillAmount takes a value between 0 and 1. The other way is to move the anchor position. The difference lies in what the user wants. fillAmount will only shows parts of the image and reveals it as it goes towards 1, while the anchor position will stretch the image showing the entire image at all time.
You said, "Ins$$anonymous$$d of decreasing the fill amount every frame." Would I put this in my update function? Also what would I set doneTime to? 0 would be when the fillrate was done, but if you divide 0 into something you get 0. I really appreciate the help and am starting to see where you are going with this, but I am still confused.
doneTime would be the amount of time that has passed since the timer started. Since you want the bar to decrease you probably want multiplierFillImg.fillAmount = 1 - (doneTime / maxTime);
Your answer
Follow this Question
Related Questions
Make Fillamount Match Timer 1 Answer
Having a speed counter 2 Answers
How to make a chronometer ?? 2 Answers
Speed Affect Timer 1 Answer
Oxygen Tank Progress Bar 1 Answer