Search Unity

  1. Get all the Unite Berlin 2018 news on the blog.
    Dismiss Notice
  2. Unity 2018.2 has arrived! Read about it here.
    Dismiss Notice
  3. We're looking for your feedback on the platforms you use and how you use them. Let us know!
    Dismiss Notice
  4. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Learn more.
    Dismiss Notice
  6. ARCore is out of developer preview! Read about it here.
    Dismiss Notice
  7. Magic Leap’s Lumin SDK Technical Preview for Unity lets you get started creating content for Magic Leap One™. Find more information on our blog!
    Dismiss Notice
  8. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

[Documentation] UnityEvent.RemoveAllListeners() only removes non persistent listeners

Discussion in 'Documentation' started by Nanity, Jul 18, 2015.

  1. Nanity

    Nanity

    Joined:
    Jul 6, 2012
    Posts:
    148
    jannis99 likes this.
  2. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    2,909
    What do you mean by "non persistent listeners" ?
     
  3. Nanity

    Nanity

    Joined:
    Jul 6, 2012
    Posts:
    148
    UnityEvent contains a list of delegates that are called upon an event (e.g. OnClick() in the Button UI component). If you add new delegates via inspector they are "persistent" and can't be removed by script. On the other hand, if you call UnityEvent.AddListener(UnityAction) by script, it will add a "non persistent" delegate, that will not show up in the inspector.

    All public functions of UnityEvent only allow to remove "non persistent" listeners/delegates that were added by script. Those who were added via inspector only can be removed via the inspector. UnityEvent.RemoveAllListeners() implies to be able to remove "persistent" listeners although this is not true (tested!).
     
    dmlightup, fazhom, jannis99 and 2 others like this.
  4. Julien-Lynge

    Julien-Lynge

    Joined:
    Nov 5, 2010
    Posts:
    117
    Thanks Nanity!

    The whole persistent vs non-persistent listeners thing doesn't appear to be documented, so that was a helpful explanation.

    With that info, I poked through the UnityEngine source and come up with a solution for adding inspector (persistent) events via script. You just have to use reflection to get at the private method AddPersistentListener, which expects a delegate reference (and optional CallState).

    This is a problem I've found with the event system in general - not only is the documentation less than stellar, but it doesn't appear to have been set up with the intention of being heavily modifiable by the user. It's actually a rather nice system, and I hope they continue to expand it when they (someday) update the Input class, but hopefully in the meantime the community can continue to put together its own documentation and
     
  5. Nanity

    Nanity

    Joined:
    Jul 6, 2012
    Posts:
    148
    It's a nice piece of code yes. If they would rip out Unity Editor Drawers as seperate dll, they would have to rewrite a bunch of code because they call a lot of internal functions that are not available to us.

    Reflection works, but if you want to make deep changes you have so much clutter.

    Improvements might to be taken up into the Documentation, not sure what's the best communication channel though. This forum? Bug reports? Mail to the support? PM to Unity Employees?
     
  6. ChrisSch

    ChrisSch

    Joined:
    Feb 15, 2013
    Posts:
    763
    Thank you! I've been confused for a couple days why isn't adding/removing listeners working, been through countless google searches, until I found your post which explains what a persistent listener is, and that you can't manipulate one, and that non persistent listeners don't show up in inspector. Once I removed the persistent listeners, and added them through code, everything started working.

    Wish I knew how to add/remove persistent listeners though.
     
  7. duck

    duck

    Unity Technologies

    Joined:
    Oct 21, 2008
    Posts:
    356
    Hi Nanity, thanks for your post and your detailed follow-up. This is really useful and I'll make sure the manual gets updated!
     
    ChrisSch likes this.
  8. Petethegoat

    Petethegoat

    Joined:
    Jun 12, 2013
    Posts:
    34
    Is there a method to count the number of non-persistent listeners?
    Nothing in the documentation that I can see- there's GetPersistentEventCount, but as the name suggests, it only returns the number of persistent listeners.
     
    CinnoMan likes this.
  9. amanpu

    amanpu

    Joined:
    Feb 12, 2015
    Posts:
    8
    It is worth noting that you can also remove persistent listeners from onClick event or any other event as following:
    1. gameObject.GetComponent<Button>().onClick = new Button.ButtonClickedEvent();
     
  10. duck

    duck

    Unity Technologies

    Joined:
    Oct 21, 2008
    Posts:
    356
    I've updated the docs, the info you've provided about persistent vs non persistent listeners will be in the next online update :) thanks!
     
    Nanity, amanpu and Petethegoat like this.
  11. duck

    duck

    Unity Technologies

    Joined:
    Oct 21, 2008
    Posts:
    356
    The updated info is now online :)
     
    Nanity likes this.
  12. James3545

    James3545

    Joined:
    Nov 21, 2016
    Posts:
    6
    Any update on if we will be able to get info on the non persistent listeners? Seems we can still only see the persistent ones. I would like to know how many non persistent listener are on an event.
     
  13. rus89

    rus89

    Joined:
    Apr 22, 2015
    Posts:
    4
    If somebody need example how to remove persistent listener from code in editor, I found solution :)

    Code (CSharp):
    1.  
    2.         //Button on which you want to remove persistent listeners
    3.         Button inAppBackButton = inAppMenuGameObject.transform.GetChild(1).GetComponent<Button>();
    4.  
    5.         //Define what Method you want to call, and add it later as persistent listener
    6.         UnityEngine.Events.UnityAction action = gameControllerMenu.menus.settings.GetComponent<SettingsMenu>().ClickSoundPlay;
    7.         //or
    8.         UnityEngine.Events.UnityAction action1 = new UnityEngine.Events.UnityAction(gameControllerMenu.menus.settings.GetComponent<SettingsMenu>().ClickSoundPlay);
    9.  
    10.         //Define method with one argument
    11.         UnityEngine.Events.UnityAction<GameObject> actionWithGO = gameControllerMenu.menuManagerScript.ShowMenu;
    12.         //or
    13.         UnityEngine.Events.UnityAction<GameObject> actionWithGO1 = new UnityEngine.Events.UnityAction<GameObject>(gameControllerMenu.menuManagerScript.ShowMenu);
    14.  
    15.         //Remove all previous persistent listeners
    16.         UnityEditor.Events.UnityEventTools.RemovePersistentListener(inAppBackButton.onClick, 1);
    17.         UnityEditor.Events.UnityEventTools.RemovePersistentListener(inAppBackButton.onClick, 0);
    18.  
    19.         //Add new void persisten listener
    20.         UnityEditor.Events.UnityEventTools.AddVoidPersistentListener(inAppBackButton.onClick, action);
    21.  
    22.         //Add new persistent listener with GameObject as argument
    23.         UnityEditor.Events.UnityEventTools.AddObjectPersistentListener<GameObject>(inAppBackButton.onClick, actionWithGO, gameControllerMenu.menus.videoForCoinsMenu);
    24.  
    Hope someone will find it useful. Cheers.
     
  14. Keyserjaya99

    Keyserjaya99

    Joined:
    Nov 17, 2016
    Posts:
    2
    But it's works only on editor, sad... :' (
    Is there any way to make it works on runtime(build version)?
     
    dmlightup likes this.
  15. dmlightup

    dmlightup

    Joined:
    Jun 7, 2017
    Posts:
    11
    I would also be interested in hearing about workarounds for doing this in runtime. Thanks for the useful explanation @Nanity