Search Unity

Button On Click execution order?

Discussion in 'Scripting' started by larswik, Sep 28, 2017.

  1. larswik

    larswik

    Joined:
    Dec 20, 2012
    Posts:
    312
    Quick question. I looked at the Doc for Button for On Click and the Unity Events for the info but did see it.
    When my button is clicked it performs 2 On Click events. The top most event gets data from the Input field. Second On Click makes the Input field inactive and it disappears. There is a reason I am not doing this in code.

    My concern is that they will fire out of order and it will try and get data from the Input Field that has been deactivated. Is there a firing order, top to bottom?
     
    webjaros likes this.
  2. Circool

    Circool

    Joined:
    Feb 5, 2013
    Posts:
    56
    webjaros likes this.
  3. larswik

    larswik

    Joined:
    Dec 20, 2012
    Posts:
    312
  4. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    According to the documentation its undefined. But in practice it seem to go top to bottom.
     
  5. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    916
    I've seen the code myself, and it does have a very specific order. A UnityEvent holds two lists, one for serialized listeners added in the inspector, and another for listeners added at runtime. after the UnityEvent is deserialized or when a listener is added/removed programatically, the UnityEvent then builds a 3rd list which is a concatenation the previous two and uses that as the call order when Invoke() is called. any invalid invocations get skipped. so any incomplete listener in the inspector or listener whose reference was destroyed are invalid invocations and are skipped, but are still present in the list.

    Thus, listeners shown in the inspector are called in the order shown first, then listeners added programatically are called in the order they were added. Tim C might be talking about how the Delegates being combined has no concrete order specified, and thats true.... but looking closely at when its merging the delegates you'll notice that it actually doesn't affect the call order at all, so they'll always run in the order I mentioned earlier.

    More likely what Tim C was saying is that the implementation might change so don't rely on it. but its been that way for years, and it doesn't look like its changing anytime soon.
     
  6. larswik

    larswik

    Joined:
    Dec 20, 2012
    Posts:
    312
    This sounds good to me. I had already taken a different approach to solve my problem but this is good to know for future projects that there is a order and I can rely on it.

    Thanks!
     
    unnanego likes this.
  7. TheFastLane

    TheFastLane

    Joined:
    Aug 27, 2018
    Posts:
    5
    @josh
    Great detailed answer!
     
  8. cfireborn

    cfireborn

    Joined:
    Apr 2, 2020
    Posts:
    2
    Hopping on this in 2021- it seems that the order is indeed undefined, I've got a button taking a

    AddListener(delegate { SendEmail(inputtedEmailAddress.text); });
    as well as a different method attached to the button's onClick in the inspector, and it appears that the listener added programmatically is added first, then the one in the inspector- opposite of the expected order given @josh 's detailed and awesome answer :(
     
  9. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    916
    This is the first time I've heard of this. Its also the first time I've seen someone pass it in as an explicit delegate. Is it the same issue if you simply pass in a method group (a reference to an existing function)? this is how I've always added listeners to unity events
     
  10. AFriendlyUnityDeveloper

    AFriendlyUnityDeveloper

    Joined:
    Dec 26, 2018
    Posts:
    33
    You CANT rely on it, it works, but you cant rely on it long term.

    Undefined in situations like this typically means that they make no promises about the order it gets called in.

    So yes, there is an order today (unless they are using a random number generator to call these functions then of course there would be). But they could refactor this code tomorrow and that could break your code. So be careful, this is the sort of thing that an upgrade on library/unity dependency could easily break.
     
    Shack_Man and Kurt-Dekker like this.