Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
0
Question by worldsbestboss · Mar 28, 2015 at 01:26 AM · buttonreferencedelegatelistener

Button Listener Takes Reference But I Want to Pass Value?

I've got a list of Button objects and I want to give each of them a different return value so that a function will know which button was clicked/what that button corresponds to. To do this I iterate through a List of Buttons and then give each a listener with the index value of the for loop.

The problem (I believe) is that the listener takes the index variable as a reference and passes that to the listener rather than the actual index value. So the result of having a List of 5 Buttons would be that each would return the value of i (which would be 5 at the end of the for loop) rather than returning 0, 1, 2, 3, 4, 5. The below code shows what I'm trying to do.

 public List<Button> buttons;

 void Start()
 {
     for(int i=0; i<buttons.Count; i++)
     {
         buttons[i].onClick.AddListener(() => TellFunc(i));
     }
 }
 
 void TellFunc(int index)
 {
     Debug.Log("this is button #" + index);
 }

TLDR; Is there any way to make it so that the Button.onClick listeners will take the argument as a value rather than a reference?

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

1 Reply

· Add your reply
  • Sort: 
avatar image
7
Best Answer

Answer by purdyjo · Mar 28, 2015 at 02:50 PM

I believe all you need to do here is create a temporary integer within the for loop to store the integer, and pass that temporary integer into the listener.

integers are passed by value by nature, just as any basic data type and struct, so I am suprised that it doesn't work with just passing i into the listener, but all you should have to do is something like this

 for(int i=0; i<buttons.Count; i++)
 {
     int tempInt = i;
     buttons[i].onClick.AddListener(() => TellFunc(tempInt ));
 }

and it should work the way you want, having each button return individual numbers instead of all of them returning 5 with a list of 5 buttons as an example

Comment
Add comment · Show 3 · 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 Marrt · May 20, 2016 at 11:49 PM 0
Share

This does not work. Common sense would tell one that tempInt only exists in the scope of the current iteration, but it persists somehow and always gets the last value of i-1 (because the last increase of i is not submitted to it), it behaves like a global variable.

here is more: http://forum.unity3d.com/threads/how-to-add-non-persistent-unityaction-with-a-single-parameter-to-a-buttons-onclick-event.267047/

avatar image Bunny83 Marrt · May 21, 2016 at 01:48 AM 1
Share

This does work. You should read about closures and what they actually close around. The variable "i" is declared outside of the for loop and is the same for each iteration. That's why the original code does always print the last assigned value because every closure will reference the same variable.

In the solution in this answer the closure will close over the local "tempInt" variable. Each iteration will have a new fresh variable. Don't say it doesn't work when you haven't tested this exact code example.

If it doesn't work for you, you probably have something different which might cause a different behaviour. However such a case doesn't belong into a comment on an answer to a different question. Ask a seperate question if you want to have your case sorted out. Feel free to reference this question

avatar image metallizard · Jun 23, 2016 at 09:15 AM 0
Share

This is what i really looking for. Well actually i want to AddListener with Dictionary full of delegates instances but it doesn't work at all !

I tried to use List and this problem happen to me.. when i try to call

buttons[i].onClick.AddListener(() => TellFunc[i]());

it didn't work ! but when i swap i to tempInt it work like charm ! well my code is not as good as i want if it use Dictionary but hey ! its finally working !

THAN$$anonymous$$ YOU SO $$anonymous$$UCH !!

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

24 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

Related Questions

Creating a button, giving it a delegate (or Action), and giving that delegate a reference parameter 0 Answers

Method added on a button click with a delegate is being called twice. 0 Answers

Any way to pass the function of a listener as a string? 1 Answer

Pass in a reference directly into a script so that it update the appropriate variable value when the slider is moved. 0 Answers

Reference For Button Which Calls OnClick 4 Answers


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