• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
Question by brobes05 · Jul 10, 2017 at 08:14 AM · c#unity 5uibuttonarrays

Add Listeners to array of Buttons

Hi, using unity 5.6 -

I have three buttons that I am attempting to instantiate with listeners in C#. In my function TaskOnClick(), I want to be able to be able to tell w$$anonymous$$ch button has been clicked so I can add further functionality.

I am fairly sure I am mucking up some code in the Start() function and also not sure if I need to add a bool to the TaskOnClick() function or if I should just use IF or Switch statements to parse through the clicks. I have been following t$$anonymous$$s example: https://docs.unity3d.com/ScriptReference/UI.Button-onClick.html

Here is my code:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;
 
 public class Button02 : MonoBehaviour {
 
     public Button[] buttons;
 
     private void Start()
     {
         for (int i = 0; i < buttons.Length; i++)
         {
             Button btns = buttons[i].GetComponent<Button>();
             btns.onClick.AddListener(TaskOnClick);
         }
 
     }
 
     public void TaskOnClick()
     {
         // how can I add a boolean here to check w$$anonymous$$ch button has been clicked?
         Debug.Log("you have clicked t$$anonymous$$s button");
     }
 }

I am wondering if somet$$anonymous$$ng along the lines of t$$anonymous$$s in TaskOnClick() might work: (obviously t$$anonymous$$s is very crude....) Thank you in advance.

 public void TaskOnClick() {
      for (int i= 0; i < Lenght; i++) {
           if (buttons[0] == true)
                 'do somet$$anonymous$$ng'....
          else if(buttons[1] == true)
                 'do somet$$anonymous$$ng else'




Comment
Voidcao
mihajlo99nestorovic
honza_unity823

People who like this

3 Show 0
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
Best Answer

Answer by Hellium · Jul 10, 2017 at 01:10 PM

All the answers given previously won't work because of the closure problem.

W$$anonymous$$le the idea of using a specific delegate it the way to go, you have to "capture" the value of the loop index before assigning the delegate :

  for (int i = 0; i < buttons.Length; i++)
  {
        int closureIndex = i ; // Prevents the closure problem
        buttons[closureIndex].onClick.AddListener( () => TaskOnClick( closureIndex ) );
  }

  // ...
  public void TaskOnClick( int buttonIndex )
  {
      Debug.Log("You have clicked the button #" + buttonIndex, buttons[buttonIndex]);
  }

Comment
CoryButler
brobes05
RealSoftGames
kalljuha
lo_whng
Braza
atifmahmood29
dbrowndev
PixelFireXY
Voidcao
triangle4studios
FG-VC
Rapizer
mihajlo99nestorovic
jnzhuang
And 3 more...

People who like this

18 Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image CoryButler · Jul 10, 2017 at 01:41 PM 0
Share

I was unaware of the closure problem. The solution appears to do logically-speaking the same thing, but you are right. C# understands your code differently than mine. Thanks for the info.

avatar image brobes05 · Jul 10, 2017 at 09:51 PM 0
Share

@Hellium and @CoryButler -

I appreciate your responses. It has solved the issue of adding a listener. Thank you.

avatar image RealSoftGames · Nov 17, 2018 at 01:42 PM 0
Share

thank you i spent over 6 hours trying to figure out why my code wouldnt work. weirdly enough i have never heard of this closure problem, could you please explain why adding a new int param inside a for loop and assigning it the iterators value works. essentially using i in the for loop should do the exact same thing?

avatar image Hellium RealSoftGames · Nov 17, 2018 at 02:33 PM 0
Share

I may not be the best one to explain the problem, but I will try.


 for (int i = 0; i < buttons.Length; i++)
 {
      buttons[closureIndex].onClick.AddListener( () => TaskOnClick( i ) );
 }

With the previous code, you add a new listener to the onClick event. This listener in the following UnityAction : () => TaskOnClick( i ) . When one of the button is clicked, TaskOnClick is called, but it's not the value of i at the ith iteration which is used as the argument. It's a "reference" of i. Since there is 99,99% chance the for loop has ended beforehand, i contains the value buttons.Length.


By creating a new variable inside the loop, when TaskOnClick( closureIndex ) is called, the reference of the temporary variable is used as the parameter, and the problem disappears.


I hope it's clear enough for you.

avatar image

Answer by CoryButler · Jul 10, 2017 at 12:36 PM

@brobes05

Use a delegate to pass the button's ID as an argument. Also, skip the btns variable.

 for (int i = 0; i < buttons.Length; i++)
 {
      buttons[i].GetComponent<Button>().onClick.AddListener(delegate{TaskOnClick(i);});
 }

Then, change the TaskOnClick() signature to TaskOnClick(int id).

Comment
Hellium
brobes05
wordrun

People who like this

1 Show 0 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

389 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to keep your button selected after clicking away ??? 1 Answer

UIButton highlighted color not working 0 Answers

Button only works once 1 Answer

Unity 5: UI button OnPointerDown not function as expected 1 Answer

Unity - keep created buttons after quit 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges