Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Resolved Second slider line of code never sets value

Discussion in 'Scripting' started by Boogafreak, Jun 25, 2020.

  1. Boogafreak

    Boogafreak

    Joined:
    Oct 2, 2017
    Posts:
    42
    Hi.

    I really tried a lot to make this go away :|

    The whole scene is 2 sliders and a button.
    The 2 sliders should be set to certain values at start of scene, but whatever I do, one slider always starts at 0.
    It can be moved and remembered, but it appears at 0 on start.
    I've debugged the GameParameters values and they are not 0.

    The issue was pinned to these 2 lines :
    fusion_speed_slider.value = (float) (GameParameters.FUSION_SPEED);
    fall_speed_slider.value = (float) (GameParameters.FALL_SPEED);

    The first line is done correctly.
    The second does not.
    When I switch their order, the other slider starts at 0.
    I verified I have the correct objects, the script is in a "SettingsManager" object which has nothing but the script.

    The whole class is tiny :

    Code (CSharp):
    1. public class SettingsSliders : MonoBehaviour
    2. {
    3.     public static Slider fusion_speed_slider;
    4.     public static Slider fall_speed_slider;
    5.  
    6.     // Sliders initialization
    7.     void Start ()
    8.     {
    9.         fusion_speed_slider = GameObject.FindWithTag("FusionSpeedSlider").GetComponent<Slider>();
    10.         fall_speed_slider = GameObject.FindWithTag("FallSpeedSlider").GetComponent<Slider>();
    11.  
    12.         // read settings values first from registry
    13.         GameManager.instance.MyGetPrefKeyInt(ref GameParameters.FUSION_SPEED, "FUSION_SPEED");
    14.         GameManager.instance.MyGetPrefKeyInt(ref GameParameters.FALL_SPEED, "FALL_SPEED");
    15.  
    16.         // set sliders to current values - only first line works :(
    17.         fusion_speed_slider.value = (float) (GameParameters.FUSION_SPEED);
    18.         fall_speed_slider.value = (float) (GameParameters.FALL_SPEED);
    19.  
    20.         // set slider and GameParameters at values
    21.         SettingsChanged(0f);
    22.     }
    23.        
    24.  
    25.     // Change in setting on start and via sliders
    26.     // Called also on sliders movement
    27.     public void SettingsChanged(float slider_value) // float is not used. was for debug test...
    28.     {
    29.         // set all sliders values into parameters
    30.  
    31.         // game speed slider
    32.         GameParameters.FUSION_SPEED = (int)(fusion_speed_slider.value);
    33.         GameParameters.WAIT_BEFORE_POP = ((100-fusion_speed_slider.value)/100f)+0.1f;
    34.         GameParameters.WAIT_AFTER_POP = GameParameters.WAIT_BEFORE_POP / 2f;
    35.  
    36.         // fall speed slider
    37.         GameParameters.FALL_SPEED = (int)(fall_speed_slider.value);
    38.         GameParameters.ANIMATION_SPEED = (GameParameters.FALL_SPEED/40f) + 0.5f; // this is a fall speed multiplier
    39.  
    40.         // [save them on pressing ReturnToMenu() button]
    41.     }
    42.  
    43.     // Update is called once per frame
    44.     void Update ()
    45.     {
    46.        
    47.     }
    48. }
    49.  

    Please. Any ideas?
    Any flush I need to do to some strange slider memory?
    Oh, yes, I'm still on a 2017 unity version... but that shouldn't make an impact.

    Thanks in advance, Booga.
     
  2. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,120
    Trying using Debug.Log() to try printing out the value you're trying to assign to the slider, to see that it isn't 0.

    Also, unrelated, but it's pretty uncommon to use all upper case property/field names in C#. Usually that implies those values are constants, but you're clearly using them as mutable values. That's not the cause of your problems, but it's the kind of thing that could cause confusion.
     
  3. Boogafreak

    Boogafreak

    Joined:
    Oct 2, 2017
    Posts:
    42
    The upper case variables are variables... I will change the names laterzzz :}
    They were constants until now. Now they are (supposed to be) connected to sliders ;)
    Both are defined as "public static int".

    About the values - I did check. Extensively.
    There are 3 points to check -
    1. at start of start()
    2. the GameParameters values after loading from registry.
    3. the value of the sliders.

    Here they are on a test :
    error_log.jpg

    You can see the default values at start (40,60).
    Registry loads (52, 56)
    then, after the 2 lines, 52 is set into first slider value, but the second slider value is 0.
    I also checked the sliders aren't null.

    Note that switching the 2 ".value=" lines changes which slider doesn't work :[

    Also note that other than this 0 value, all other functionality works - it changes the game speed, and when I set the sliders and exit, the slider value is remembered correctly by another function. Just when entering the scene the slider starts at 0.
     
    Last edited: Jun 25, 2020
  4. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,120
    Well, you're on the right track. I don't know where in your code you had those "Start", "loaded", and "value" debug statements, but it's clear that some time between "loaded" and "value", the value is being changed. Make sure there isn't another script accessing that slider and setting its value. Add more Debug.Log if you need to in order to determine the exact line the value changes to 0. If you're only ever setting the value within in the Start method, then something else must be setting the value. It can only do that if it either has a direct reference to the slider (so, some other script of yours is changing it) or maybe there's some script on the slider itself doing something.

    Also, try adding a third slider as kind of a copy of the 2nd slider, and see if the same thing happens. That might help narrow down what's causing the second one to misbehave.
     
  5. Boogafreak

    Boogafreak

    Joined:
    Oct 2, 2017
    Posts:
    42
    Thanks for your replies.

    "Loaded" debug was just before the 2 lines , debugging GameParameters values.
    Then the 2 lines :
    "fusion_speed_slider.value = (float) (GameParameters.FUSION_SPEED);
    fall_speed_slider.value = (float) (GameParameters.FALL_SPEED);"
    Then a debug for value of sliders.

    This is why I pinned this to these 2 lines.
    The slider has no other script and is not referenced from anywhere. It's only purpose is to set other GameParameters.
    It is not the second slider fault too - as the first slider has this issue if I switch the 2 lines!

    I will try adding 2 more sliders and see how this changes the situation, as that was planned.
    Just thought solving it for 2 would be easier before I go on. :|
     
  6. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,120
    In that case, you should also print out the value of GameParameters.FALL_SPEED before or just after assigning it to the slider value. I'd assume it has a value of 0.
     
    Boogafreak likes this.
  7. Boogafreak

    Boogafreak

    Joined:
    Oct 2, 2017
    Posts:
    42
    It had value 56 :(

    Here's the code for totally checking everything :
    Code (CSharp):
    1.         Debug.LogError ("BoogaError : loaded : " + (int)GameParameters.FUSION_SPEED + " , " + (int)GameParameters.FALL_SPEED);
    2.  
    3.         // set sliders to current values - only first one works :(
    4.         fusion_speed_slider.value = (float) (GameParameters.FUSION_SPEED);
    5.         Debug.LogError ("BoogaError : middle : " + (int)GameParameters.FUSION_SPEED + " , " + (int)GameParameters.FALL_SPEED);
    6.         fall_speed_slider.value = (float) (GameParameters.FALL_SPEED);
    7.         if (fall_speed_slider == null)
    8.             Debug.LogError ("BoogaError : NULL value " );
    9.         Debug.LogError ("BoogaError : value : " + (int)fusion_speed_slider.value  + " , " + (int)fall_speed_slider.value );
    10.  
    Result :
    error_log2.jpg


    This means something indeed happened to GameParameters.FALL_SPEED!! :)
    I think as the first value changes, it calls SettingsChanged, which sets GameParameters.FALL_SPEED to 0.... I think I can go on from here! :)

    Thanks again for pushing me to debug between these 2 lines :)
     
    Last edited: Jun 25, 2020
  8. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,120
    Did you somehow set the MaxValue on your slider to 0?

    upload_2020-6-25_11-30-30.png
     
  9. Boogafreak

    Boogafreak

    Joined:
    Oct 2, 2017
    Posts:
    42
    Naaaah, it's 100. and "whole numbers"
     
  10. Boogafreak

    Boogafreak

    Joined:
    Oct 2, 2017
    Posts:
    42
    Solution summary :
    Reason for bug : Setting slider.value creates a call to SettingsChanged, where the values are changed.
    Solution code :
    Code (CSharp):
    1.        
    2.         int fusion_sp = GameParameters.FUSION_SPEED;
    3.         int fall_sp = GameParameters.FALL_SPEED;
    4.         fusion_speed_slider.value = (float) (fusion_sp);
    5.         fall_speed_slider.value = (float) (fall_sp);
    6.  
    It works!
    Thank you dgoyette!
     
    dgoyette likes this.
  11. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,120
    Ah, I see, so you've gone some kind of execution order problem. You're calling SettingsChanged when you assign a value to the first slider, which causes it to assigning the 2nd slider's uninitialized value of 0 to the GameParameters.FALL_SPEED. That makes sense.
     
    Boogafreak likes this.
  12. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,120
    Glad you sorted it out. That solution looks reasonable to me.
     
  13. Boogafreak

    Boogafreak

    Joined:
    Oct 2, 2017
    Posts:
    42
    I agree..
    An even better solution I think would be to place each slider with his own "SettingChanged" function.
    That way the code for one slider isn't called when another changes.