Search Unity

Dropdown Addlistener does not work after scene change

Discussion in 'Scripting' started by spootymilk, Jul 20, 2018.

  1. spootymilk

    spootymilk

    Joined:
    Jun 9, 2017
    Posts:
    18
    Hi,

    I've a probleme with a list of dropdowns. The dropdowns is part of my UI gameobject witch is dontdestroyonload.
    the code to initialize it is :

    Code (CSharp):
    1. for (int i = 0; i < HearingTypeDropDown.Count; i++) {
    2.             int tempprefvalue = (int)CurrentHearingType;
    3.             HearingTypeDropDown [i].ClearOptions ();
    4.             HearingTypeDropDown [i].onValueChanged.RemoveAllListeners ();
    5.             HearingTypeDropDown [i].AddOptions (HearingTypeOptions);
    6.             HearingTypeDropDown [i].value = tempprefvalue;
    7.             HearingTypeDropDown [i].onValueChanged.AddListener ((value) => ChooseHearingType ((HearingType)value));
    8.         }
    it calls well the function ChooseHearingType, but if i load an other scene, it does not work anymore.

    I don't understand why, beacuse i have an other list of dropdowns (also part of my ui gameobject) witch is initialize by this code :

    Code (CSharp):
    1. for (int i = 0; i < OutputDropdownCanal1.Count; i++) {
    2.             int tempprefvalue = (int)CurrentOutput[Canal.Canal1];
    3.             OutputDropdownCanal1 [i].ClearOptions ();
    4.             OutputDropdownCanal1 [i].onValueChanged.RemoveAllListeners ();
    5.             OutputDropdownCanal1 [i].AddOptions (options);
    6.             OutputDropdownCanal1 [i].value = tempprefvalue;
    7.             OutputDropdownCanal1 [i].onValueChanged.AddListener ((value) => ChooseOutput (Options2Output (value), Canal.Canal1));
    8.         }
    and these dropdowns work perfectly... (it call in this case the ChooseOutput function)

    if someone can tell me where i am making a mistake, i will be very thankfull !!!

    Spootymilk
     
  2. FernandoHC

    FernandoHC

    Joined:
    Feb 6, 2018
    Posts:
    338
    Can you confirm if the dropdown still works visually? after you change the scene can you still drop an pick the from the list?
     
  3. spootymilk

    spootymilk

    Joined:
    Jun 9, 2017
    Posts:
    18
    yes i confirm !
     
  4. FernandoHC

    FernandoHC

    Joined:
    Feb 6, 2018
    Posts:
    338
    I'm a bit puzzled on why you would have a different behavior as the codes look the same.
    Are yo using Unity's default Dropdown? I usually use TMP_Dropdown but I think it extends Dropdown so I guess I could still apply the same logic.

    Just general testing, but have you added a debug log on the start of ChooseHearingType to make sure it is not being called? Have you checked the console for any errors?

    Try having a coroutine observe the status of the onValueChanged so you can have an idea at what time they are getting null, if they are.

    If that doesn't help we might need more information, like the rest of the code of the same stack.
     
  5. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    1. Check if your listeners get called:
    Code (CSharp):
    1. .AddListener ((value) => {
    2.      Debug.Log("Called");
    3.      ChooseHearingType ((HearingType)value;
    4. });
    2. If they aren't called, then something either removed them on load, or you've messed up somewhere.

    Without the rest of the code it's hard to tell.
     
  6. spootymilk

    spootymilk

    Joined:
    Jun 9, 2017
    Posts:
    18
    I add :
    Code (CSharp):
    1. .AddListener ((value) => {
    2.      Debug.Log("Called");
    3.      ChooseHearingType ((HearingType)value;
    4. });
    Yes it is the Unity default dropdown.

    in the first scene, if i change the dropdown value (by clicking on it) the function is well called and the debug.log appears in the console.

    If I load an other scene, if i change the dropdown value (still by clicking on it) the function is not called and the debug log doesn't appears.

    what is strange, after i load the second scene, it doesn t work, but if i call the init function (with a button) again after the second scene is loaded, it work again ! It is like, a part of my code removes the listener... I check everywhere it could happen, but i don't find.

    Edit :
    More strange, if i call the function directly with a persistant onValueChange (define in the editor) the debug appears ! So if the problem was that somewhere in my code it delete the non persistent onValueChange, the log normally won't appears, am i right ?
     
  7. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    It would be much easier to help if you provided more information, for example more code.

    My guess is though, that the code snippet you posted is part of a script that belongs to an object which doesn't survive the scene change. Unity's event system is written in a way that it skips destroyed instances.

    The debugger will probably help you out here to get an idea of what's going on exactly.

    Anyway, DontDestroyOnLoad can generally be pretty evil, as you always have the risk of keeping references to objects that are no in a valid state (with regards to Unity). Either you re-initialize these parts properly, or you let DontDestroyOnLoad creep into all places where it is required, to keep those wildly-wired systems up.

    My recommendation is always to not use it at all, unless it is absolutely required (i.e. keeping huge CAD model instances alive). Everything else can usually be initialized from scratch in a very clean manner.
     
  8. FernandoHC

    FernandoHC

    Joined:
    Feb 6, 2018
    Posts:
    338
    I agree with @Suddoha , I don't really see a need for keeping such low cost objects between scenes. I'd just make it part of a hud init and be happy with it.
    But the best way to do this really is by debugging, open the code in visual studio and attach to unity at runtime. Have a global reference on your code for HearingTypeDropDown and keep observing as the code goes through, you will have to find something that is changing it.