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
1
Question by Firedan1176 · Nov 01, 2015 at 01:23 AM · uibuttonfor-looponclick

List of Buttons: Adding a listener passes Last element?

Let me give you a simplified version of my script:

 using UnityEngine.UI;
 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class Whatever : MonoBehaviour {
     //Pretend this is a list with 5 or so elements
     List<GameObject>() myGos = new List<GameObject>();
     
     
     void Start() {
         for(int i = 0; i < myGos.Count; i++) {
         string nameThing= i.ToString();
 
         myGos[i].GetComponent<Button>().onClick.AddListener(() => DebugNumber(nameThing));
         }
     }
 
     public void DebugNumber(string num) {
         Debug.Log(num);
     }
 }


Now don't look for little errors here because I just typed up a quick example of what I'm wanting. Okay, so let's say that I now have 4 or so buttons, and each one should have a listener in onClick() so that once I click one, it will print a number, whichever one was assigned i in the for loop above. So, if I click all the buttons, I should get a mix of numbers 1-4. Do I? No. I am getting 4 for All of Them.

So what's the problem?

If I print nameThing in my for loop, I will get the 1-4 I want. If I print nameTHing when DebugNumber is called when I click a button, I get ONLY 4. Why? And how can I fix it?

Thank you.

Edit:

If this looks like it's working for you, try replacing the DebugNumber(nameTHing()); line with DebugNumber(i.ToString()));, then it won't work.

WHY? WHy do I need to set i.ToString() Before I add the listener?

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
0
Best Answer

Answer by Firedan1176 · Nov 01, 2015 at 02:23 AM

I have since discovered what my issue is, that because I have a simplified code in my question, you guys were not able to detect any significant problems.

In my code that was not provided, I have used the simplified version in a coroutine, and after moving the stuff between the for loop to a new function and passing the index, I was able to achieve the result I was wanting without any problems.

Again, thank you for everyone's response.

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
avatar image
0

Answer by Bunny83 · Nov 01, 2015 at 02:08 AM

Well, since this doesn't seem to be your actual code the question is quite pointless. The behaviour you're describing would appear when your closure is capturing the for variable "i".

In your case you create a local string variable that get captured by the closure so that problem shouldn't occur.

So for example if you would do this:

  void Start() {
      for(int i = 0; i < myGos.Count; i++) {
      myGos[i].GetComponent<Button>().onClick.AddListener(() => DebugNumber(i.ToString()));
      }
  }
 

In this case when you have 5 buttons in the list you will always see the number "5" since that's the last number i will contain. All closures have captured the same variable "i" and therefore will see the last value when executed.

However your code uses a local string variable inside the for loop. This will create a "new" variable each iteration and each closure will capture an individual variable. It doesn't have to be a string variable. This does work as well:

 void Start() {
     for(int i = 0; i < myGos.Count; i++) {
         int localVar = i;
         myGos[i].GetComponent<Button>().onClick.AddListener(() => DebugNumber(localVar.ToString()));
     }
 }

So considering your code in your question we can't reproduce that problem.

Now don't look for little errors here ...

Well, what do you consider little errors? It doesn't really matter how "little" an error is if it causes the problem...

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 Firedan1176 · Nov 01, 2015 at 02:20 AM 0
Share

Thanks for your response, by Little Errors, I meant spelling errors, capitalize errors, that kind of stuff. But I have since then found out what the issue was. Thanks for the response.

avatar image Bunny83 · Nov 01, 2015 at 02:23 AM 1
Share

btw this is nothing new ^^

http://stackoverflow.com/questions/271440/captured-variable-in-a-loop-in-c-sharp

http://aakinshin.net/en/blog/dotnet/closures/

http://blog.roboblob.com/2012/09/30/dot-net-gotcha-nr2-loop-variables-and-closures/

Additional problems with coroutines:
- http://answers.unity3d.com/questions/494640/capturing-a-variable-in-a-closure-behaves-differen.html
- http://answers.unity3d.com/questions/974036/c-lambda-call-in-for-loop-references-to-last-objec.html

avatar image Firedan1176 Bunny83 · Nov 01, 2015 at 02:24 AM 0
Share

Thank you so much for the help, and have a good weekend.

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

39 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

Related Questions

button.onClick.AddListener(method); NOT Working 1 Answer

Runtime UI button creation: can't make an "OnClick" where I call a function from another script while sending a parameter. 2 Answers

Calling preset Button OnClick events from another script 3 Answers

Button.onClick.AddListener(() => Attack()); isn't running function math correctly 1 Answer

Button OnClick() after Scene restart is Missing (Object) 2 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