Search Unity

Slider bar stepping?

Discussion in 'UGUI & TextMesh Pro' started by TroyDavis, Sep 9, 2014.

  1. TroyDavis

    TroyDavis

    Joined:
    Mar 27, 2013
    Posts:
    78
    Anyone know of a way to make the new Slider bar allow for step intervals? I want to have a quality slider That allows for 5 different settings.
     
  2. TroyDavis

    TroyDavis

    Joined:
    Mar 27, 2013
    Posts:
    78
    Nevermind guys I figured it out!
     
  3. Deleted User

    Deleted User

    Guest

    Hi TroyDavis,
    how Do you do that?
     
  4. TroyDavis

    TroyDavis

    Joined:
    Mar 27, 2013
    Posts:
    78
    On the Slider you have Min Value, Max Value, a bool for Whole Numbers, and a Value.
    if you want 6 steps on the slider just set Min Value to 0, Max Value to 5, and check Whole Numbers.

    If you would rather start at 1 then set them to 1 and 6 respectively.
     
  5. unic

    unic

    Joined:
    Oct 24, 2016
    Posts:
    3
    But what about to make it from 0 to 1000 stepping by 10?
     
    astechnolabs likes this.
  6. Hosnkobf

    Hosnkobf

    Joined:
    Aug 23, 2016
    Posts:
    1,096
    Thanks for digging out a 3.5 years old thread :D

    Your example covers 100 steps. so make the bar from 0 to 100 and multiply the value with 10 in your code.
     
  7. labandunga

    labandunga

    Joined:
    Aug 1, 2012
    Posts:
    29
    Digging a 4.5 year old thread wouldn't be a problem if Unity wasn't daft enough to delete Unity Answers.
     
  8. ObjectObject

    ObjectObject

    Joined:
    Oct 25, 2020
    Posts:
    1
    I'm from 2020 :(
     
    leenamho likes this.
  9. Dans97

    Dans97

    Joined:
    Nov 19, 2019
    Posts:
    5
    Hey! This is a simple code to help you guys out! You'll have to attach this script to your slider component, then hook the UpdateStep() function to the OnValueChanged event in the Editor. Hope it helps!

    Code (CSharp):
    1. public class UISliderStep : MonoBehaviour
    2. {
    3.     int stepAmount = 100;
    4.     Slider mySlider = null;
    5.  
    6.     int numberOfSteps = 0;
    7.  
    8.     // Start is called before the first frame update
    9.     void Start()
    10.     {
    11.         mySlider = GetComponent<Slider>();
    12.         numberOfSteps = (int) mySlider.maxValue / stepAmount;
    13.     }
    14.  
    15.     public void UpdateStep()
    16.     {
    17.         float range = (mySlider.value / mySlider.maxValue) * numberOfSteps;
    18.         int ceil = Mathf.CeilToInt(range);
    19.         mySlider.value = ceil * stepAmount;
    20.     }
    21. }
     
  10. Hobby-Game-Developer

    Hobby-Game-Developer

    Joined:
    Aug 27, 2017
    Posts:
    14
    Use that :
    upload_2021-3-11_14-20-40.png
    Just Mathf.RoundToInt()
     
  11. EvilBritishGuy

    EvilBritishGuy

    Joined:
    Apr 22, 2016
    Posts:
    1
    I just added the method below to Slider's list of events and then divide the max value of the slider by 5 accordingly.

    e.g for values from 0 to180. min is set to 0, max is set to 36.

    public void SetSliderAmount(float _value)
    {
    someFloat = (int)(_value * 5);
    }
     
  12. JPraxedes

    JPraxedes

    Joined:
    Oct 22, 2019
    Posts:
    1
    I know there must be better answers for the question but after encountering with this page several times and trying my own, i finally went this way, sorry for necromancing the page again in 2022, hope it helps somebody:

    public Slider mySlider;
    public float step;

    public void SliderClamp()
    {
    for (float i = mouseSlider.minValue; i <= mouseSlider.value; i += step)
    {
    if(mySlider.value < i && mySlider.value > i-step) mySlider.value = i;
    else if (mySlider.value > i && mySlider.value < i+step) mySlider.value = i+step;
    }
    }


    Attaching the slider in the inspector and calling the method on value change will clamp the value to the nearest step possible (Works for me with min/max values set to 0.5/4.5 and step to 0.2)
     
  13. AxelBusch

    AxelBusch

    Joined:
    Oct 8, 2015
    Posts:
    4
    The basic calculation required to limit a Slider value to discrete steps is no more than this:

    Code (CSharp):
    1.  
    2. float steppedValue = Mathf.Round(slider.value / StepSize) * StepSize;
    3.  
    Below my class that wraps that makes this a convenient component. Simply save it as UISliderStep.cs and add it to the Slider component, then set your value for Step Size.

    The class registers a lister for changes to the Slider and updates it with the desired stepped value.
    When running in the editor, the class will also complain if the value for Step Size is too large to make sense.

    Cheers!

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.UI;
    4.  
    5. /// <summary>
    6. /// Attach this script to a Unity.UI Slider component to control the step size within the slider range.
    7. /// </summary>
    8. [RequireComponent(typeof(Slider))]
    9. public class UiSliderStep : MonoBehaviour
    10. {
    11.  
    12.     [Tooltip("The desired difference between neighbouring values of the Slider component.")]
    13.     [MinAttribute(0.0001f)]
    14.     public float StepSize = 0.0001f;
    15.  
    16.     private Slider _slider;
    17.  
    18.     void Start()
    19.     {
    20.         _slider = GetComponent<Slider>();
    21.         if (_slider != null)
    22.         {
    23.             _slider.onValueChanged.AddListener(ClampSliderValue);
    24.         }
    25.     }
    26.  
    27.     /// <summary>
    28.     /// Calculates the nearest stepped value and updates the Slider component.
    29.     /// </summary>
    30.     /// <param name="value">Current slider value</param>
    31.     public void ClampSliderValue(float value)
    32.     {
    33.         if (_slider != null && StepSize > 0)
    34.         {
    35.             float steppedValue = Mathf.Round(value / StepSize) * StepSize;
    36.             if (steppedValue != value)
    37.             {
    38.                 _slider.value = steppedValue;
    39.                 Debug.Log(string.Format("New stepped Slider value: {0}", _slider.value));
    40.             }
    41.  
    42. #if UNITY_EDITOR
    43.             // Help find non-sensical values during development. Gets stripped out for platform build.
    44.             int _numberOfSteps = (int)((_slider.maxValue - _slider.minValue) / StepSize);
    45.             if (_numberOfSteps < 1 || steppedValue < _slider.minValue || steppedValue > _slider.maxValue)
    46.             {
    47.                 Debug.LogWarning(string.Format("StepSize is too large. Consider reducing StepSize to less than {0}.", _slider.maxValue - _slider.minValue));
    48.             }
    49. #endif
    50.         }
    51.     }
    52. }
    53.  
    54.  
     
    ul_antnasce and futer24 like this.
  14. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,276
    Hi old thread!
    Thanks for solutions but why did Unity not think to add a step option - either number of steps or step size (float), while keeping the min/max values to what you actually want to get out of it?! Hoping better design in next UI
     
    dr4 and lazyrain like this.
  15. MontanaAnton

    MontanaAnton

    Joined:
    Feb 16, 2014
    Posts:
    14
    My little solution :)
    use at your own risk

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.EventSystems;
    3. using UnityEngine.UI;
    4.  
    5. public class SliderSmooth : Slider
    6. {
    7.     [SerializeField] float steps = 100f; //smoothed steps
    8.     float horizontalAxis;
    9.     float verticalAxis;
    10.     float holdTime;
    11.     float lastPressTime;
    12.  
    13.     protected override void Update()
    14.     {
    15.         if (!wholeNumbers)
    16.         {
    17.             if (IsVertical())
    18.             {
    19.                 verticalAxis = Input.GetAxis("Vertical");
    20.                 UpdateSliderValue(verticalAxis);
    21.  
    22.             }
    23.             else
    24.             {
    25.                 horizontalAxis = Input.GetAxis("Horizontal");
    26.                 UpdateSliderValue(horizontalAxis);
    27.  
    28.             }
    29.         }
    30.         base.Update();
    31.     }
    32.  
    33.     public bool IsVertical()
    34.     {
    35.         return (direction == Direction.BottomToTop || direction == Direction.TopToBottom);
    36.     }
    37.     public override void OnMove(AxisEventData eventData)
    38.     {
    39.         if (IsVertical())
    40.         {
    41.             if (wholeNumbers)
    42.             {
    43.                 UpdateSliderValue(verticalAxis);
    44.             }
    45.  
    46.             if (verticalAxis != 0)
    47.             {
    48.                 return;
    49.             }
    50.         }
    51.         else
    52.         {
    53.  
    54.             if (wholeNumbers)
    55.             {
    56.                 UpdateSliderValue(horizontalAxis);
    57.             }
    58.  
    59.             if (horizontalAxis != 0)
    60.             {
    61.                 return;
    62.             }
    63.         }
    64.  
    65.         base.OnMove(eventData);
    66.     }
    67.  
    68.  
    69.     public void UpdateSliderValue(float axis)
    70.     {
    71.         if (axis != 0)
    72.         {
    73.             CheckAndSetLastTime();
    74.             SliderUpdate(axis);
    75.         }
    76.         else
    77.         {
    78.             ResetHoldTime();
    79.         }
    80.     }
    81.  
    82.     public void ResetHoldTime()
    83.     {
    84.         lastPressTime = 0;
    85.         holdTime = 0;
    86.     }
    87.     public void CheckAndSetLastTime()
    88.     {
    89.         if (lastPressTime == 0)
    90.         {
    91.             lastPressTime = Time.time;
    92.         }
    93.         holdTime = Time.time - lastPressTime;
    94.     }
    95.  
    96.     public void SliderUpdate(float inputAxis)
    97.     {
    98.         //inverse
    99.         if (direction == Direction.TopToBottom || direction == Direction.RightToLeft)
    100.         {
    101.            inputAxis = inputAxis*-1;
    102.         }
    103.  
    104.         if (wholeNumbers)
    105.         {
    106.             value = value + Mathf.Round(inputAxis);
    107.         }
    108.         else
    109.         {
    110.        
    111.             float range = maxValue - minValue;
    112.             value = value + ((range * holdTime) / steps) * inputAxis;
    113.         }
    114.    
    115.     }
    116. }
    117.  
    118.  
     
    Last edited: Oct 25, 2022