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 how do you add a UnityAction<int> to OnPointerDown in a button?

Discussion in 'Scripting' started by laurentlavigne, Jan 26, 2021.

  1. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    5,994
    upload_2021-1-25_17-36-54.png
    what's the proper form for both?
     

    Attached Files:

  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    Button.OnPointerDown is not an event. It's how the Button knows that the pointer is down; not something you can subscribe to. So the exact thing you are asking is impossible.

    You could write your own component implementing IPointerDownHandler and add that to the same GameObject, and make that do whatever you want.

    Or you could subscribe to some actual event that already exists, like Button.onClick. The syntax for that would be
    Code (CSharp):
    1. button.onClick.AddListener(() => onClickDelegate(index));
    You can't add onClickDelegate directly because the argument list is incompatible, so you need to wrap it in another function, which is done here using a lambda expression. Note that this captures the variable "index" in a closure, not its current value, so if you change the value of "index" after doing this you will be changing what gets called when the button is clicked.
     
    laurentlavigne likes this.
  3. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,756
    laurentlavigne likes this.
  4. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    5,994
    does
    Method (index, delegate);
    ...
    Method(int i, UnityAction<int> delegate)
    {
    button.onClick.AddListener(delegate(i));
    }

    capture the value or the variable 'index'?
     
  5. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    Neither, because you didn't use any lambda expressions anywhere in that example. Also, it won't compile.

    But if you replaced "delegate(i)" with "() => delegate(i)", then it would capture the variable
    i
    , which is local to that particular invocation of the function. Which is effectively the same as capturing the value of "index".
     
  6. chehob

    chehob

    Joined:
    Oct 25, 2017
    Posts:
    8
    Do I need to remove the listener if the button gets destroyed at runtime? Is there a way to store this wrap function reference for future RemoveListener?
     
  7. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    As far as I'm aware, UnityEvents automatically take care of clearing delegate references when destroyed.