Search Unity

OnClick on button from code

Discussion in 'UGUI & TextMesh Pro' started by HappyLDE, Aug 23, 2014.

  1. HappyLDE

    HappyLDE

    Joined:
    Apr 16, 2014
    Posts:
    56
    I can't find how to detect clicks on a button from code, like mouse down, mouse up after mouse down?

    Thanks
     
    Simoky99 and Xiph like this.
  2. User340

    User340

    Joined:
    Feb 28, 2007
    Posts:
    3,001
    Don't use Button, use EventTrigger instead.
     
    youssef15102010 and santi8ago8 like this.
  3. HappyLDE

    HappyLDE

    Joined:
    Apr 16, 2014
    Posts:
    56
    This seems counter-intuitive as the first time i hear about it. Is there any example?

    Thanks!
     
  4. HappyLDE

    HappyLDE

    Joined:
    Apr 16, 2014
    Posts:
    56
    Like this?
    Code (CSharp):
    1. void Start()
    2.     {
    3.         Button b = gameObject.GetComponent<Button>();
    4.         b.onClick.AddListener(delegate() { StartGame("Level1"); });
    5.     }
    6.    
    7.     public void StartGame(string level)
    8.     {
    9.         Application.LoadLevel(level);
    10.     }
     
  5. Luiz_Thiago

    Luiz_Thiago

    Joined:
    Feb 27, 2013
    Posts:
    32
    Not working here =(

    Code (csharp):
    1.  
    2. public void SetupButton () {
    3.      var button = transform.GetComponent<Button>();
    4.      button.onClick.AddListener(delegate () { this.ButtonClicked(); });
    5. }
    6.  
    7. public void ButtonClicked () {
    8.      _buildStructureGUI.SelectedPool = _structurePool;
    9. }
    10.  
     
    Ash-Blue likes this.
  6. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    Do you need to set it up from code? e.g. Do you have procedurally generated buttons?

    Setting it up in the Editor is much easier (and the 'expected' use).
     
  7. Luiz_Thiago

    Luiz_Thiago

    Joined:
    Feb 27, 2013
    Posts:
    32
    Its procedurally =/
     
  8. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    Have you tried referring directly to the function as a delegate, as opposed to creating an in-line delegate that calls the function?
    (I haven't, but I feel like this should work)
    Code (csharp):
    1.  
    2. public void SetupButton () {
    3.      var button = transform.GetComponent<Button>();
    4.      button.onClick.AddListener(this.ButtonClicked);
    5. }
    6.  
    7. public void ButtonClicked () {
    8.      _buildStructureGUI.SelectedPool = _structurePool;
    9. }
    10.  
    I'm not sure how one would add parameters to this. I would've expected that AddListener would have a second parameter that could become the callback's parameter (equivalent to that third 'box' in the Inspector).
     
  9. Luiz_Thiago

    Luiz_Thiago

    Joined:
    Feb 27, 2013
    Posts:
    32
    I've tried too, but without success ... I have the impression that it is necessary to mark the delegate as persistence ... But I do not know how ...
     
  10. senc01a

    senc01a

    Joined:
    Dec 26, 2012
    Posts:
    5
    Same thing, still trying to figure out how to have the handler function receive the actual button, or anything else as a parameter.

    I think it can be done using the new UnityAction, but I can't manage to get it right.
     
    Last edited: Aug 26, 2014
  11. ldb

    ldb

    Joined:
    Apr 30, 2013
    Posts:
    40
    You just need to remove the parentheses from where you are setting delegate...

    This is working fine for me...

    Code (csharp):
    1.  
    2.     public void setupBtn()
    3.     {
    4.         string param = "bar";
    5.         btn.GetComponent<Button>().onClick.AddListener(delegate { btnClicked(param); });
    6.     }
    7.        
    8.     public void btnClicked(string param)
    9.     {
    10.         Debug.Log("foo " + param);
    11.     }
    12.  
    13.  
    Outputs "foo bar", as one would expect.
     
  12. gavi

    gavi

    Joined:
    Mar 30, 2013
    Posts:
    10
    Thank you ldb: it works.

    For curiosity, in the Editor Inspector, the OnClick listener of the button does not appear. Is it normal?
     
    PyiPyi likes this.
  13. AntFitch

    AntFitch

    Joined:
    Jan 31, 2012
    Posts:
    243
    I noticed the same problem. Listener does not appear, but it works. Looks like the list isn't being refreshed. I reported this as a bug.
     
  14. gavi

    gavi

    Joined:
    Mar 30, 2013
    Posts:
    10
    thanks Amaranth
     
  15. AntFitch

    AntFitch

    Joined:
    Jan 31, 2012
    Posts:
    243
    That reminds me! Found an easier way to do what we all seem to be trying to do. It turns out that Unity 4.6 has a built-in feature for this. This is how I used it:

    1. In the Project Tab, create a new script called MyEventListener.
    2. Paste this code into the script:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.EventSystems;
    3.  
    4. public class MyEventListener : MonoBehaviour, IPointerClickHandler
    5. {
    6.     private float clickTime;            // time of last click
    7.     private int clickCount=0;         // current click count
    8.     public bool onClick = true;            // is click allowed on button?
    9.     public bool onDoubleClick = false;    // is double-click allowed on button?
    10.    
    11.     public void OnPointerClick(PointerEventData data)
    12.     {        
    13.         // get interval between this click and the previous one (check for double click)
    14.         float interval = data.clickTime - clickTime;
    15.  
    16.         // if this is double click, change click count
    17.         if (interval < 0.5 && interval > 0 && clickCount != 2)
    18.             clickCount = 2;
    19.         else
    20.             clickCount = 1;
    21.  
    22.         // reset click time
    23.         clickTime = data.clickTime;
    24.            
    25.         // single click
    26.         if (onClick && clickCount == 1)
    27.         {
    28.             // enter code here
    29.         }
    30.    
    31.         // double click
    32.         if (onDoubleClick && clickCount == 2)
    33.         {
    34.             // enter code here
    35.         }
    36.    
    37. }
    3. Drag this script on to your button game object (or attach it via code).
    4. Set the onClick and onDoubleClick bools (you may want one click on some objects, double-click on others, etc)

    (updated with small changes)
     
    Last edited: Feb 1, 2017
    tokar_dev and rakkarage like this.
  16. 0mr_ashutosh0

    0mr_ashutosh0

    Joined:
    Jul 9, 2014
    Posts:
    5
    @amaranth Will this script work for Touch Input. if not what changes i should make ?
     
  17. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    The script should work with touch.
     
  18. 0mr_ashutosh0

    0mr_ashutosh0

    Joined:
    Jul 9, 2014
    Posts:
    5
    But how the click is associated with touch ? im bit confused here :( . well atleast i should try it out first hehe
     
  19. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    A 'click' is a higher level concept. It's when you down and up on the same alement. So a 'click' for a touch is when you put your finger down and up on the same element.
     
  20. DA_ATeam

    DA_ATeam

    Joined:
    Dec 6, 2012
    Posts:
    5
    Thanks for the awesome code amaranth! I know it's a year later and big changes have come about, but in Unity 5.1 I got the following error. My hack(see attached script) was to hit the button and have it play an Animator trigger animation. Scripting is not my forte as you can tell. I have an 'Idle' animation that is transitioned to a 'Throw' animation. The 'Throw' animation has a trigger parameter. Every time the button is hit, the 3D player throws a ball. It would be a milestone to get this part working. Thanks in anticipation
     

    Attached Files:

    ktpttd likes this.
  21. sstadelman

    sstadelman

    Joined:
    Dec 17, 2013
    Posts:
    12
    This approach is the closest I've found to the intended goal: pass a parameter in the onClick method. Very nice!

     
    Powersx and olonge like this.
  22. ciathyza

    ciathyza

    Joined:
    Aug 16, 2015
    Posts:
    109
    I know thread is old but I'm trying to assign click handlers to UI buttons that are in a prefab and loaded at runtime. But it's not working. I use the same way as described by ldb above.

    Is there anything else I need to take care of? An EventSystem exists in the scene (although I'm not sure it's really needed for this).

    My code looks like this:

    Code (CSharp):
    1. GameObject uiObj = ResourceUtil.InstantiatePrefab("Prefabs/UI/Main Menu UI", "UI");
    2. uiObj.transform.SetParent(gameObject.transform, false);
    3. Button[] buttons = uiObj.GetComponentsInChildren<Button>();
    4. foreach (Button button in buttons)
    5. {
    6.     button.onClick.AddListener(() => OnUIButtonClick(button));
    7. }
    8.  
    9. private void OnUIButtonClick(Button button)
    10. {
    11.     Log.Debug("OnUIButtonClick: " + button);
    12. }
     
  23. ciathyza

    ciathyza

    Joined:
    Aug 16, 2015
    Posts:
    109
    Nevermind! I had to add a GraphicRaycaster to the Canvas object that is used as a parent for my menu object. Now it works.
     
  24. miladloveboth

    miladloveboth

    Joined:
    Dec 27, 2015
    Posts:
    2
    //first we have using the UI, so...
    Using UnityEngine.UI;
    //and before ..in Start void....
    public Button yourButton;//yourButton is namebutton
    public Button yoursecondButton ;
    void Start ()
    {
    yourButton .onClick .AddListener (() => { // yourButton must be like first part

    print ("hello people");//print hello people or anything in massagebar
    //or
    Application .LoadLevel ("urSence");//load a sense after on click and ursence is name sence
    //or
    yoursecondButton .enabled = false or true;//yoursecondButton is on or off

    });



    }
     
  25. n1troov4

    n1troov4

    Joined:
    Oct 25, 2013
    Posts:
    1
    Code (CSharp):
    1.  public Transform DebugPanel;
    2.     public GameObject DebugText;
    3.  
    4.  
    5.     void Start()
    6.     {
    7.         var db = new DataService();
    8.         foreach (var ss in db.DBUsers)
    9.         {
    10.             GameObject Local = Instantiate(DebugText);
    11.  
    12.             Local.GetComponentInChildren<Text>().text = "User: " + ss.idUsers + " " + ss.Login;
    13.             Local.GetComponentInChildren<Button>().onClick.AddListener(delegate () { ShowWhatWasCliked(ss); });
    14.             Local.transform.SetParent(DebugPanel);
    15.         }
    16.     }
    17.  
    18.     private void ShowWhatWasCliked(DBUsers ss)
    19.     {
    20.         Debug.Log(ss.Login);
    21.     }
     
  26. ramees

    ramees

    Joined:
    Oct 25, 2018
    Posts:
    1
    Here is a simple video demonstration of how to add onclick event to button
     
  27. Appleeowee

    Appleeowee

    Joined:
    Apr 28, 2020
    Posts:
    1
    does this work for a 2D game?
     
  28. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    Yes, this has to do with the UI, nothing specifically to do with 2D or 3D.
     
    ForceVII likes this.
  29. pharamodel4567

    pharamodel4567

    Joined:
    Jan 17, 2021
    Posts:
    3
    if i have 100 btn and i need one function onclick for to 100 btn what is the solution for that
     
  30. CsSSteven

    CsSSteven

    Joined:
    Feb 9, 2023
    Posts:
    1
    why?