Search Unity

Setting slider value over time using C# script?

Discussion in 'Scripting' started by deejaydunno, Jan 3, 2016.

  1. deejaydunno

    deejaydunno

    Joined:
    Dec 29, 2015
    Posts:
    8
    I've tried asking this over on Answers, but I think because it's such a newbie question people are glancing over it. I've been playing around with a couple of ways to do this but it doesn't seem to be working. I'm trying to achieve the following - On button click, launching a script that changes a slider value from 0.85 to 1.15 over an amount of time. I've tried using :

    Slider.value = Mathf.Lerp(0.85F,1.15F,Time.deltaTime /5);

    in the hope that it would go from one value to the other over 5 seconds, but instead it just seems to change the value after 0.85 back and fourth (eg 0.85xxx). I've spent the last 2 days trying to get my head around why Lerp isn't working and I'm pretty confident it's something I'm using Lerp wrong. I am also wondering if using the Lerp command is even the best way to do what I'm after? I don't want the value to change until the button is clicked, and once another button is clicked I want the value to go back to normal. How is the best way to achieve this? Any help is appreciated!
     
  2. Lentaq

    Lentaq

    Joined:
    Apr 8, 2015
    Posts:
    57
    (Time.deltaTime / 5) is probably giving you a microscopically small number. deltaTime is the time between each frame Update() or something like that, as I recall. And, since you could be getting 100+ frames per second, that number is tiny.

    If you use Lerp correctly, it should do what you are wanting, though. It's designed to do what you think. It's just a matter of getting it set up correctly.

    The best article I've seen on using Lerps is the following:

    blueraja

    I recommend everyone read this, since Lerp is used improperly even by Unity devs. It focuses on vectors, I believe, but it's the same principle.

    This one looks like it gives a fair explanation of different use cases, also(I didn't fully read it, tbh):

    unitydojo

    Unity also has their own little article on Lerp:

    unity
     
  3. kru

    kru

    Joined:
    Jan 19, 2013
    Posts:
    452
    Time.deltaTime represents the time between each frame. It will generally be a value that is very small, such as 0.01f, and it won't fluctuate very much under normal circumstance. As far as the Lerp is concerned, Time.deltaTime is basically a constant that is very close to 0. This is sort of what the code is doing:
    Code (csharp):
    1. Slider.value = Mathf.Lerp(0.85f, 1.15f, 0 / 5);
    every frame.

    Instead, you need to add to an accumulated value, and lerp over that.
    Code (csharp):
    1. // delcare some value to store the accumulated time
    2. float totalSliderTime =0f;
    3.  
    4. // inside of your update or animation method
    5. totalSliderTime += Time.deltaTime;
    6. Slider.value = Mathf.Lerp(0.85f, 1.15f, totalSliderTime / 5);
    I suggest starting a coroutine to animate your slider value.
    Code (csharp):
    1. IEnumerator AnimateSliderOverTime(float seconds)
    2. {
    3.      float animationTime = 0f;
    4.      while (animationTime < seconds)
    5.      {
    6.           animationTime += Time.deltaTime;
    7.           float lerpValue = animationTime / seconds;
    8.           Slider.value = Mathf.Lerp(0.85f, 1.15f, lerpValue);
    9.           yield return null;
    10.      }
    11. }
     
    namdo and Magiichan like this.
  4. Lentaq

    Lentaq

    Joined:
    Apr 8, 2015
    Posts:
    57
    That coroutine mentioned by kru will work to get you there(to a value of 1, which would be the max value 1.15f), but it won't get you back to a value of 0(which is where 0.85f is).

    So, you are going to need to do some tweaking to get it to go back to 0.85f on the next button click.
     
  5. deejaydunno

    deejaydunno

    Joined:
    Dec 29, 2015
    Posts:
    8
    Excellent, thanks for your help! That's given me a direction to go to, so I'm seriously grateful!
     
  6. deejaydunno

    deejaydunno

    Joined:
    Dec 29, 2015
    Posts:
    8
    Yeah see now I have more problems. The above code does indeed change the value of the slider, but it starts changing the second the program is run as opposed to starting on a button press. I can't seem to find a way to do this because it has to go in Update or it only gets run once. I tried making a script to start another script on the button press, but that doesn't seem to want to work either, again probably due to my lack of knowledge. The only way I can find out what to do is by using Google, and then I usually see several different ways to achieve it yet can't seem to get any of them to actually work. The problem being, I actually have no idea what I'm really doing, I picked up Unity 4 days ago and have no experience with coding other than a small bit of ActionScript a few years ago, and even then I only learnt what I needed to at the time, and all has been forgotten, although it would be useless here. This really is the last bit of coding I need to get done, so I'm eager to get these functions working. I understand a whole lot more than I did 4 days ago, but in the grand scheme of things I still know nothing!
     
  7. deejaydunno

    deejaydunno

    Joined:
    Dec 29, 2015
    Posts:
    8
    OK, remarkably I've got everything done, aside one thing.... Resetting the value so each time the button gets clicked, it starts from 0.85F again instead of where it got stopped lerping. I've tried to reset the value of the slider back to 0.85F on click before the script containing the lerp command is executed, but after reading this post I understand it doesn't matter what I set it to, the lerp needs to be reset to 0 because the lerp command will always pick up from where it left off in regards to the start and the end point, not a value I set. So my final question (I hope!) how do I reset the lerp? I've looked for answers and I've sat here trying for an hour or too, but it either throws me an error or it just doesn't reset..... Or I just don't understand. This is the last thing I need to do before I can call it a day!
     
  8. kru

    kru

    Joined:
    Jan 19, 2013
    Posts:
    452
    Perhaps you need to reset the value of the accumulated variable to 0 when the button is clicked.
     
  9. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    can you post your updated code, it'll help us help you easier :)
     
  10. deejaydunno

    deejaydunno

    Joined:
    Dec 29, 2015
    Posts:
    8
    Yes I need to reset the value, but I can't work out how. I have a script called Clicked which when clicked, enables the lerp script (lets call it LerpStart) to start doing it's thing. That works fine. What I now need to work out is how to change the slider.Value in the LerpStart script from the Clicked script. I've Googled it and I keep finding answers, but they all seem to be different, and I can't seem to implement them successfully!

    In the Clicked script I have:
    Code (csharp):
    1.  
    2.     public void ButtonClick ()
    3.     {
    4.         LerpStart script;
    5.         script = GetComponent<LerpStart>();
    6.         script.enabled = true;
    7.     }
    8.  
    That happily enables the LerpStart script, and the value starts to change. What I can work out is how (and to a degree, what) to tell the Clicked void to change the Lerp progress in the LerpStart script so I can set it back to 0.

    The other thing I'm guessing now is by changing the slider.Value, I won't actually be resetting the Lerp, I'll just be resetting the starting point. Does that mean if the Lerp total time is 60 seconds and it gets reset 30 seconds though, the next Lerp will take the remaining 30 seconds or will it reset back to 60? I've used the following code from above:

    Code (csharp):
    1.  
    2. totalSliderTime += Time.deltaTime;
    3. Slider.value = Mathf.Lerp(0.85f, 1.15f, totalSliderTime / 60);
    4.  
    Wouldn't I need to change the position of the Lerp, rather than the slider.Value? Sorry for all the questions, and thanks for the help!!
     
    Last edited: Jan 4, 2016
  11. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,338
    LeftyRighty likes this.
  12. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    you can store the start time as a float like so:
    Code (csharp):
    1.  
    2. float startTime = Time.time;
    3.  
    if you have that in your "lerp start" and work out "time since start" by doing
    Code (csharp):
    1.  
    2. totalSliderTime = Time.time - startTime;
    3.  
    you'll have the "total time since the last time the button was clicked"


    forget the slider for a moment, it just does what it's told at the end. Concentrate on "getting" the lerp setup.
     
  13. deejaydunno

    deejaydunno

    Joined:
    Dec 29, 2015
    Posts:
    8
    Thanks everyone, finally managed what I needed to. Can't thank you enough for pointing me/giving me the right direction!
     
  14. manbearpigman

    manbearpigman

    Joined:
    Feb 29, 2020
    Posts:
    37
    super easy way:

    IEnumerator UpdateSlider() //updates the slider value
    {
    float value = (float)currentXP / xpToNextLevel;
    if (levelProgressSlider.value < value)
    {
    levelProgressSlider.value += 0.001f; ; //tick up
    yield return new WaitForSeconds(0.001f); //each second
    StartCoroutine(UpdateSlider()); //loop
    }

    }