Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • 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
2
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 which 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 this 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 which button has been clicked?
         Debug.Log("you have clicked this button");
     }
 }

I am wondering if something along the lines of this in TaskOnClick() might work: (obviously this is very crude....) Thank you in advance.

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




Comment
Add comment
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
16
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.

While 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
Add comment · 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 $$anonymous$$e. 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
1

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
Add comment · 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.

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

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

Почему после перехода на другую версию Unity при создании кнопки она не откликается на геймпад и клавиатуру? 0 Answers

How to keep your button selected after clicking away ??? 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