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

Question [Range()] dont work properly

Discussion in 'Scripting' started by kinglotrich, Sep 17, 2023.

  1. kinglotrich

    kinglotrich

    Joined:
    Jun 2, 2023
    Posts:
    22
    I put [Range()] header like in picture and want this value is default 100 at least for percentage calcutations but, when I leave it as it is, it returns zero always so ı have to adjust them something higer than 100 in inspector and make them 100 again to get 100 value.so I tried to write strength = 100, but still returns zero if I never change value how can I make them get their min value whatever happen ?

    upload_2023-9-17_20-33-43.png

    upload_2023-9-17_20-33-19.png
     

    Attached Files:

  2. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,588
    Please use code tags instead of screenshots for code.

    Are you maybe assigning a value in start/awake or some other place which overwrites your default?
     
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    The RangeAttribute is only applied in very specific time windows.

    It does not (generally) "guard" the value from going outside its range.

    You are also assigning a value to a public / serialized field. This runs you into these complications:

    Serialized fields in Unity are initialized as a cascade of possible values, each subsequent value (if present) overwriting the previous value:

    - what the class constructor makes (either default(T) or else field initializers, eg "what's in your code")

    - what may be saved with the prefab

    - what may be saved with the prefab override(s)/variant(s)

    - what may be saved in the scene and not applied to the prefab

    - what may be changed in the scene and not yet saved to disk

    - what may be changed in OnEnable(), Awake(), Start(), or even later

    Make sure you only initialize things at ONE of the above levels, or if necessary, at levels that you specifically understand in your use case. Otherwise errors will seem very mysterious.

    Here's the official discussion: https://blog.unity.com/technology/serialization-in-unity

    If you must initialize fields, then do so in the void
    Reset()
    method, which ONLY runs in the UnityEditor.

    Field initializers versus using Reset() function and Unity serialization:

    https://forum.unity.com/threads/sensitivity-in-my-mouselook-script.1061612/#post-6858908

    https://forum.unity.com/threads/crouch-speed-is-faster-than-movement-speed.1132054/#post-7274596

    To avoid complexity in your prefabs / scenes, I recommend NEVER using the
    FormerlySerializedAsAttribute
     
    Bunny83 likes this.
  4. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,495
    Right, the Range attribute only affects the GUI of the inspector and the slider parameters. So only when you interact with the slider will those limits be applied since the slider can only work in those specified ranges.

    However since you "set" a default value in code by providing a field initializer, did you actually have this field initializer BEFORE you added the script to the object, of have you added it AFTER the script had been added to the object? Because the field initializer only comes into affect once and that's when you actually add the script to the object. After that the value is serialized and stored in a prefab or scene. Changing the field initializer afterwards has no effect on the value. You could click "Reset" on the component which could fix that. But of course you might loose other values you had already setup.

    Try adding this script to a new gameobject and see what value it actually has. Though as Kurt mentioned, the Range attribute does nothing on its own. it's just metadata that is used by the inspector UI to display a slider instead of a normal input field. Those just specify the slider range and does not magically limit the field itself.
     
  5. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,495
    If you want to protect yourself from inputting wrong values, you can always add a clamp in Awake to ensure the values are in the desired range. However instead of automatic clamping, doing some kind of assert checks is usually better. Display a warning when the value is outside of the desired / expected range.
     
  6. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,588
    I think you are misunderstanding OP, but maybe i am. I thought their core problem was that the value got overwritten (at all, by some means), not that this overwritten value fell outside of their range.
     
  7. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,495
    Well, it's hard to tell what the exact issue may be. However he said
    So I interpret this as that the field initializer wasn't there from the beginning and was added later. Of course once the object is created and serialized the field initializer doesn't have any effect anymore. Since the default value for any numberical value is 0 it just stayed at 0.

    Though what he actually meant can only be cleared up by the OP :)