- Home /
NGUI UI Slider: Progress Bar
Hello, I'm trying to use NGUI's UI Slider to make a progress bar for a game that decreases as time passes when harvesting minerals and resources. The problem is that the bars don't have a fixed maximum size to decrease from. I wanted all of the progress bars to be uniform despite having different times, but they all instead become longer the more time there is. How do I fix this?
The Bar Code: public class Harvest_Bar : MonoBehaviour {
private UISlider _slider;
private float _maxWidth;
private float _balancer;
void Awake ()
{
_slider = GetComponent<UISlider>();
_maxWidth = _slider.foreground.localScale.x;
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public void updateDisplay(float totalTime)
{
_slider.foreground.localScale = new Vector3(totalTime * 2.56f, _slider.foreground.localScale.y, _slider.foreground.localScale.z);
}
}
Code calling it:
void Update()
{
//Timer
//guiText.text = "Time Left: " + Mathf.Floor(activeTime);
if(isHarvesting || isReplinishing)
{
activeTime -= Time.deltaTime;
pb.GetComponent<Harvest_Bar>().updateDisplay(activeTime);
}
if(activeTime <= 0)
{
if(isHarvesting)
{
harvestComplete();
}
else if (isReplinishing)
{
replinishComplete();
}
}
}
Answer by Andres-Fernandez · Aug 25, 2014 at 01:24 PM
You can use a maxTime variable initialised to the maximum amount of time and then use it in the Time.deltaTime like this:
activeTime -= Time.deltaTime / maxTime;
This way, if you initialise activeTime to 1.0f, your activeTime will decrease from 1 to 0 in maxTime seconds (and you can use that as the value of your UISlider).
I'm a bit confused by the phrasing. By adding in the maxTime it does what now?
The amount of time used for it varies depending on the type of items and whether it has a short, moderate, or longer charge time.
//Set the Harvesting Time
if(harvestType == "Short")
harvestTime = 10.0f;
else if(harvestType == "$$anonymous$$oderate")
harvestTime = 30.0f;
else if(harvestType == "Long")
harvestTime = 60.0f;
else
print ("No eligible harvest type");
void Harvesting()
{
Debug.Log("Beginning Harvest");
activeTime = harvestTime;
pb.SetActive(true);
pb.GetComponent<Harvest_Bar>().updateDisplay(activeTime);
isHarvesting = true;
//set the text
}
Adding the maxTime variable helps you transform the [activeTime, 0] gap into a [1, 0] gap (which is what tye UISlider needs as its value). It is used a lot whenever you want to lerp anything over time. Something like this:
float maxTime = 5.0; // 5 seconds of movement
float time = 0.0f;
while (time < 1.0f) {
time += Time.deltaTime / maxTime;
transform.position = Vector3.Lerp(initialPosition, targetPosition, time);
}
By using Time.deltaTime / maxTime you transform an amount of time into a percentage (between 0 and 1) which can be used in any function that works within that gap.
In your case, I think you can use your harvestTime as maxTime. It would be something like this (inside Update):
if(isHarvesting || isReplinishing) {
activeTime -= Time.deltaTime / harvestTime;
pb.GetComponent<Harvest_Bar>().updateDisplay(activeTime);
}
if(activeTime < 0.0f) {
// Your harvesting is done
}
You would need to change the initialisation of activeTime variable inside the Harvesting function to this:
void Harvesting() {
// stuff...
activeTime = 1.0f;
pb.SetActive(true);
// rest of stuff...
}
I tried that but the Progress Bars simply shrink down to a sliver of the full measure. If the activeTime is initially at 1.0f and the numbers reduce that by Time.deltaTime / harvestTime then it doesn't scale it to the width of the progress bar and then shrink down. Does it need to be longer to match the 150x length?
Weren't you using a NGUI UISlider? The UISlider from NGUI only needs a value between 0 and 1. That value goes into the "value" property of the UISlider (I believe). That value makes the foreground sprite of the UISlider shrink or grow. But the foreground sprite always scales related to the background, which can be any size you want (150 px or whatever). You don't need to scale the sprite (the gameObject that contains the UISlider script). Just pass the activeTime to the UISlider and it should work.
Try making a small example first. Start making a UISlider (following tasharen's docs) and check that you can manage the value with the editor controls (and check that it is the foreground that shrinks related to the background, no matter its size). Then create an script that sets the value property of the slider.
Oh, okay. I was messing with the wrong value. It works now after that.