Search Unity

Change the Value of a Toggle without triggering OnValueChanged?

Discussion in 'UGUI & TextMesh Pro' started by webbut, Oct 20, 2014.

  1. enhawk

    enhawk

    Joined:
    Aug 22, 2013
    Posts:
    833
    just checking in here, after lots of debugging and finding this thread.

    If you want to set a toggle state from a playerpref for example - sound on / off - if you use the ".isOn" property of the toggle, it'll run the "onvaluechanged" - this is counter intuitive for a toggle state setup: I just want to change the visual appearance of my toggle to match the users existing settings, not make a new setting choice for them.

    Changing this to an onPointerClick event.

    Would be super useful / nice if there was a "toggle button start state" that we can set without firing anything.
     
    Last edited: Feb 25, 2018
    scott_unity734 and rakkarage like this.
  2. Gru

    Gru

    Joined:
    Dec 23, 2012
    Posts:
    142
    In the current system, excessive event firing is unavoidable if there are 2 UI elements that rely on the same value. This is common in cases where Options UI has both a slider and editable float Input box. I would like to see the Unity UI design team argue out of that one.
    Yes, the endless loops can be avoided by doing some "clever" checks. Here is how I've done it:
    http://www.ennoble-studios.com/tuts...ropdown-in-unity-ui-without-firing-event.html
     
    User340 likes this.
  3. aseceans

    aseceans

    Joined:
    Sep 9, 2017
    Posts:
    2
    For me, I just used a bool and set it to false if i'm initializing the toggle value in the Start() method and set it back to true after i'm done. Then in the OnValueChanged() click method I check if the value is true before saving the toggle's value to PlayerPrefs. This way yes the onValueChanged calls the method every time but if I'm setting the toggle via scripting to initialize it, I can ignore saving to PlayerPrefs. Not sure if that's helpful to anyone that but that's how I fixed my problem.
     
    Cromfeli and SimRuJ like this.
  4. duncanx

    duncanx

    Joined:
    Feb 12, 2011
    Posts:
    45
    The extension code works in most cases and is nice. If someone who understands the internals of this has time...please add support for Toggles that use ToggleGroups.
     
  5. SimRuJ

    SimRuJ

    Joined:
    Apr 7, 2016
    Posts:
    247
    Thank you so much! I had to change it to the following (2017.3.1f1, otherwise it throws an exception) but it works!:
    Code (CSharp):
    1. GameObject clickedToggle = UnityEngine.EventSystems.EventSystem.current.currentSelectedGameObject;
    2. if(clickedToggle == null) {
    3.   return;
    4. }
    I just ran into the problem because restoring settings after restarting my game also sets a toggle.

    How is there not an actual option for this yet after almost 4 years?! The more I work with Unity the more of these small annoyances (bugs?) I find and none of them has been fixed yet!
     
    Last edited: Sep 21, 2018
    rakkarage likes this.
  6. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,279
    I know right!
    Is the UI even still in active development or is it just in maintenance mode until a new system comes along?
    @phil-Unity
     
    rakkarage likes this.
  7. FireHawkX

    FireHawkX

    Joined:
    Apr 26, 2016
    Posts:
    28
    Yup... I agree as well... I have pretty much given up on unity now... there are also 2 major bugs with unity and windows 7 that prevented me from exporting to webgl with any version since version 2017... and another bug with the video player.. i reported both in september of last year, and they are both still opened... We had a game finished and ready to ship on standby for more than a year now because of engine bugs... so I decided to start learning how to use unreal now...
     
  8. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    So yes, i'm still working on the UI though i've been struggling to keep on top of internal changes and fixing larger defects.

    Also any chance someone reading the thread can create a bug and then post it here? I think this issue got lost due to no bug being on file (that i can see). I'll still get it passed off to another worker that will handle this as a "priority" but a bug would be great.
     
    Last edited: Sep 21, 2018
    AM-Dev likes this.
  9. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    You have those two bug numbers handy? Can check the status for you directly with the team responsible.
     
  10. SimRuJ

    SimRuJ

    Joined:
    Apr 7, 2016
    Posts:
    247
    @phil-Unity
    About the Toggle: @prestonmatterport created a bug report almost exactly 3 years ago (linked here): Click
    I'd be more than thankful if you could pass it along!


    I know this is off-topic but could you also please look at this (this is the other bug/feature/who knows I was talking about):
    Bug report: click (it says it's fixed but it's not!)
    One of the threads: click
    Another thread (in "Answers" this time): click

    I already contacted the support about it but according to them "...this is by design and it doesn't seem like the behavior will be changed any time soon."
    Yet there are still threads being opened about it (from 2 days ago: click) because people just don't see it as a wanted feature but more as a bug.
    The workaround suggested by support is to set a button's navigation to "None" but that causes a lot of other problems, the biggest three being:
    - You can't switch between buttons anymore using the arrow keys on your keyboard or the buttons on a controller/gamepad
    - The EventSystem has problems accessing the buttons, which means that you can't use a prefab to create 5 more buttons at runtime, then check their "onClick" (it always throws an exception)
    - It still doesn't work if you're using a touchscreen

    As JoeStrout said so fittingly in post #26 of the first thread I linked above (which is just one of the threads in which people are complaining about it, Google finds a lot more):
    "I can't show this to my client. He'll say it's a bug. If we shipped, his users would say it's a bug. It makes no sense to have two buttons highlighted at once — which one is the real current button? Who knows?"

    @Tim-C said about this in 2014:
    "We don't have seperate visual states for selected and ''highlighted' currently. We changed this behaviour in 4.6.1 so that selection and highlighitng work together (there are issues when they don't). We may add some extra visual states for this in the future."
     
    rakkarage likes this.
  11. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,279
    Ok thanks, sounds like you need a bigger team!

    But the main gist of the thread is the lack of an obvious feature isn't it? (not a bug but essential functionality) - setting up controls without triggering callbacks.
     
    mowax74 likes this.
  12. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    So that is a feedback page not a bug, unfortunately atm they are different systems and the feedback isn't really tracked by the dev team. We tend to only find out about it if we go searching. so a bug would still be helpful.

    From the history on the bug that i see, we marked it as won't fixed, then the user replied back saying it was fixed thus we changed the status to fixed after verification. The bug isn't as much related to what your talking about as it is that highlight was always staying on.

    That being said the crap answer is again please file a bug it really is the best way for us to track it. I'll see what i can do to get it resolved as well.
     
  13. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    I agree about needing a large team. Could always use more help.

    And yes maybe functionality, but way easier to track "smaller" things like this through bugs rather then a list somewhere. And i've informed the team member to look at more of the cases. If there are any in particular you'd expect by all means let us know.
     
    andyz likes this.
  14. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,279
    @phil-Unity Out of interest (and an obscure bug) has Unity UI changed between 2017.3 and latest Unity 2018?

    the bitbucket only has a 2017.3 version visible...
     
  15. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    It has, updating bitbucket has been top of my list for months now but alas as you see hasn't been updated. I'll try to find the couple hours required to update it asap.
     
    andyz likes this.
  16. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,279
    Another question (going off topic now!), can Unity UI dlls be taken from an older unity and put in newer unity to check for breaking changes to a project? Any reference for which ones?
     
  17. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    Your mileage may vary but technically "yes" you should be ok, we have not fully deprecated any API's so it should just work. They would just be the Managed C# classes (Button, Image, Text, ect), native classes (Canvas, CanvasRender, ect) are not changeable i dont think.
     
  18. scott_unity734

    scott_unity734

    Joined:
    Sep 27, 2018
    Posts:
    3
    I'm using 2018.2.7f1 and that suggestion above from @SimRuJ to add the,

    Code (CSharp):
    1.            GameObject clickedToggle = UnityEngine.EventSystems.EventSystem.current.currentSelectedGameObject;
    2.             if(clickedToggle == null) {
    3.                 return;
    4.             }
    at the beginning of my on value changed handler for the Toggle doesn't appear to work. I added a UnityEngine.Debug.LogError() with a message right before this block and right before that return.
     
  19. SimRuJ

    SimRuJ

    Joined:
    Apr 7, 2016
    Posts:
    247
    What exactly doesn't work? Does it always return "null" or always return a GameObject?
     
  20. rgonsalv

    rgonsalv

    Joined:
    Sep 29, 2016
    Posts:
    47
    I used this to do some measuring in a Text without triggering extra callbacks, thanks!
     
  21. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    864
    @phil-Unity. What is the status for implementing Set functions on the UI components? It's been a loooooong wait.
     
    Noisecrime and jashan like this.
  22. Nick_D

    Nick_D

    Joined:
    Sep 17, 2013
    Posts:
    8
    I JUST WANT TO CHANGE A PLAYER PREF WITH A TOGGLE BOX. WHYYYYYYY
     
    korimako likes this.
  23. JakubSmaga

    JakubSmaga

    Joined:
    Aug 5, 2015
    Posts:
    417
    jashan likes this.
  24. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    +1 ;-) ... this is actually a fairly common use case for a UI system: Usually, we want to get the events when the player interacts with the system, and we don't want to get any events when we change state on the UI from our code. Of course, we also have cases where we rely on the current behavior where we set something from code and then rely on the events being triggered.

    So, the solution is pretty straightforward: Keep the current API as it is, add "Set-methods" that have a "bool triggerEvents" parameter that defaults to true (or, if you already have this internally, keep it as it is). When I say triggerEvents = false, no events are being triggered. As we already have an API, those Set-methods could also never fire any events, so I could make that choice by either using the old or new API.
     
    a436t4ataf likes this.
  25. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    i've been off for a while and just getting back, i did have a conversation with a team member to have them do this while i was gone it appears to have been done for 19.1. should also have been done for all relevant classes (though if we missed one when it comes out let us know)
     
    Wolfram, triple_why, Kailric and 4 others like this.
  26. User340

    User340

    Joined:
    Feb 28, 2007
    Posts:
    3,001
  27. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    Awesome! Thanks for the update!
     
  28. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    Yup those would be the ones. As 19.1 hasn't shipped yet if there is another class you think we should do let me know ASAP and we can try our best to get it included. From our search those seemed to be the ones requiring the change.
     
    guneyozsan, MNNoxMortem and User340 like this.
  29. Scr4phead

    Scr4phead

    Joined:
    Jan 24, 2015
    Posts:
    3
    ToggleGroup has function "SetAllTogglesOff()". I suggest it too should include a "SetAllTogglesOffWithoutNotify()".
     
  30. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    "public void SetAllTogglesOff(bool sendCallback = true)" had already been added so you should be good.
     
    Circool, Scr4phead and rakkarage like this.
  31. FernandoHC

    FernandoHC

    Joined:
    Feb 6, 2018
    Posts:
    338
    Has the behavior of the toggle listener changed? I can't be certain, but seems like after I switched from 2017 to 2018.3 the Toggles now won't trigger in-code toggle isOn state change, neither from Inspector.

    Code (CSharp):
    1. toggle.onValueChanged.AddListener(ClickSwitch);
    This should work whenever I call
    toggle.isOn = bool
    , but it no longer works.

    Is this a by design behavior now?
     
    a436t4ataf likes this.
  32. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    It should only call the callback when the value changes. So if your bool is always false then it wouldn't fire if isOn == false.
     
    ExtraCat and FernandoHC like this.
  33. User340

    User340

    Joined:
    Feb 28, 2007
    Posts:
    3,001
    As a workaround, you can manually invoke the callback instead
    Code (CSharp):
    1. toggle.onValueChanged.Invoke();
     
    FernandoHC likes this.
  34. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    Note this isn't behavior that changed from what i can see in the logs. Its been like this for quite some time.
     
  35. gegagome

    gegagome

    Joined:
    Oct 11, 2012
    Posts:
    392
  36. eexxoo

    eexxoo

    Joined:
    Apr 6, 2013
    Posts:
    7
    Year: 2019



    ..and ugly code is still a part of Unity projects
     
    Flag74 likes this.
  37. User340

    User340

    Joined:
    Feb 28, 2007
    Posts:
    3,001
    What do you mean?
     
    phil-Unity and jashan like this.
  38. rgonsalv

    rgonsalv

    Joined:
    Sep 29, 2016
    Posts:
    47
    We use this to temporarily disable the callback:

    Code (CSharp):
    1.   override protected void OnEnable() {
    2.       Dropdown.DropdownEvent  handler = dropdownMenu.onValueChanged;
    3.       int handlerCount = handler.GetPersistentEventCount();
    4.       if (handlerCount > 0)
    5.         handler.SetPersistentListenerState(0, UnityEventCallState.Off);
    6.       base.OnEnable();
    7.  
    8.       if (handlerCount > 0)
    9.         handler.SetPersistentListenerState(0, UnityEventCallState.RuntimeOnly);
    10.  
    11.     }
    12.  
     
  39. _watcher_

    _watcher_

    Joined:
    Nov 7, 2014
    Posts:
    261
    @phil-Unity Please, please, please, make those SetIsOnWithoutNotify functions virtual. We need to be able to add functionality "select", and most other methods in those classes (Toggle, Dropdown, Slider,..) already are virtual, except this one. Do you need bug report for this? Thanks
     
  40. Warped

    Warped

    Joined:
    Mar 19, 2015
    Posts:
    14
    Thanks! Nice job
     
  41. Starman001

    Starman001

    Joined:
    Oct 22, 2016
    Posts:
    26
    I'm late to the party, but just for clarification, is the "fix" is Unity 2019 only ? I don't want to uplift my project again, still using 2018.3.9f1....So maybe the fix will find a way into 2018 too ? Would certainly make a bunch of people happy :)

    Big thanks to the people in this thread delivering a fix with that script extension. Wasted 3 hours today bugfixing before I found out how the toggle reacts, truly it's a bit unlucky that there is no simple state change for the code without triggering the event, I mean isn't a toggle mostly made for "settings" which must be stored and initialized ? Didn't expected that behaviour.

    However, I have the problem that while i found a workaround for my own project, the workaround posted here isn't working for me.

    I'm calling the toggle with "myToggle.SetValue(false)" to deactivate it without it triggering the event, but the event is triggered anyway :( I should notice, that I have a script attached to the onValueChanged event in the inspector, and the method i connected there is always being called. Just by using a bunch of if-else lines, I managed to achive what I want. But it honestly feels a bit unsafe for me, not sure what I did wrong. Copied the final version posted here into a new script, and at least I have no compiling errors, but also not the wanted effect. Any help ?
     
    Last edited: Jul 18, 2019
    guneyozsan likes this.
  42. Starman001

    Starman001

    Joined:
    Oct 22, 2016
    Posts:
    26
    New post, because of "spam protection" in this forum... (Sometimes I hate the internet ;) )....

    Would love to show you some code, but this annoying forum software doesn't allow me to do that. Can't post pastebin, and neither c-sharp code in the box, always get denied because of spam... F.... this, I hope my explanation above helps.
     
  43. theagemaway

    theagemaway

    Joined:
    May 21, 2017
    Posts:
    7
    This is now available (I don't know how long it's been there, but I'm on 2019.2) on several UI elements via the function "SetValueWithoutNotify"
     
    GamerFawn, cecarlsen and User340 like this.
  44. festival

    festival

    Joined:
    Feb 3, 2011
    Posts:
    80
    In some cases for a Button On/off thing you just grab the state of the toggel button "button.isOn" for your game - so there is no problem when you (at startup) change the ".isOn" which triggers the "ONValueChnaged" method..
     
  45. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,933
    Joining this epic thread in 2020, because ... I now have the opposite problem: setting .isOn from script *does not fire* the events when in Editor (only works in play mode). Thanks to all in this thread for the digging work that let me hack around the bug and force Unity to actually invoke the events even in Editor :).
     
    Wanderer13 likes this.
  46. jonaslindberg

    jonaslindberg

    Joined:
    Nov 28, 2017
    Posts:
    5
    I second this, please make it virtual. Any reason why it shouldn't be? Is there a bug report I could vote on somewhere?
     
    AM-Dev likes this.
  47. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,933
    If no-one has posted a Case number in the thread, assume no-one bothered to log the bug (there's a lot of bugs in the BugReporter, still unfixed after more than 10 years of complaining, and a few years ago it was even worse, so people probably tried and gave up)
     
  48. whj397909354

    whj397909354

    Joined:
    Oct 15, 2018
    Posts:
    1
    6 years ago
     
  49. Reahreic

    Reahreic

    Joined:
    Mar 23, 2011
    Posts:
    254
    FYI it was resolved already and the official docs were updated and listed in this post.
     
    cdr9042 likes this.
  50. Wolfram

    Wolfram

    Joined:
    Feb 16, 2010
    Posts:
    261
    @phil-Unity
    A bit late to the party, but I found another function where this might be useful (and I'm currently having exactly this situation), although it's probably a rather uncommon case:

    For a Slider, when remapping it to a different range, Unity might trigger two callbacks, of which one is unneccessary (and potentially unwanted):
    - original range: for example 0..1
    - if you now want to remap this to say 100..200, and re-initialize the value to 150, Unity will force two callbacks: one by setting .minValue to 100 (which will clamp .value to 100, triggering a callback immediately), no callback by then setting .maxValue to 200, and then the second callback (and this is the one we're actually interested in) by setting .value to 150.

    Ideally, there would be a "Slider.SetMinMaxValueWithoutNotify", which either does clamp .value to the new range but does NOT trigger any callbacks, or which leaves .value completely unmodified (but that might cause other problems, as this might cause .value to be outside the min/max range).
    Or, a luxury version would be something like Slider.RemapRange(float newMin, float newMax, float newValue), which does all of the remapping in one go, and only triggers callbacks once, for the new and final value.