So I have a script (Unity C#) that runs an IEnumerator function that generates an array of answers and I want to present them in a list format.
So I use:
public Button QuestionButton;
void Start(){
StartCoroutine(PresentQuestion());
}
IEnumerator PresentQuestion(){
CurrentStage = Stage.QuestionStart;
CurrentQuestion = "How many times do we have to do this to make it work?";
Answers.Add ("1");
Answers.Add ("2");
Answers.Add ("3");
Answers.Add ("4");
float newY = 80.0f;
foreach(string answer in Answers){
newY-=65.0f;
string locanswer = answer;
Button btn = Instantiate(QuestionButton);
btn.transform.position = new Vector3(225, newY, 0);
btn.transform.SetParent(QuestionUI.transform, false);
btn.gameObject.SetActive(true);
btn.transform.FindChild("Text").GetComponent<Text>().text = locanswer;
btn.onClick.AddListener(() => AnswerClicked(locanswer));
}
QuestionText.text = CurrentQuestion;
}
void AnswerClicked(string value){
print (value);
}
The QuestionButton is a button gameobject I linked in the inspector and it instantiates fine, the text is set fine, but it is when I add the listener.
When I go to click on the button I get the last string or _answer in the loop "every time".
I am not sure why each new Button (btn) object that is instantiated would not get its own Listener at AnswerClicked. Can anyone please explain?
FYI: QuestionUI is my canvas.
Thanks.
UPDATE :
This code works, but my previous problem still exists. I will attempt to update with my actual code.
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class Testing : MonoBehaviour {
public string CurrentQuestion;
public ArrayList Answers = new ArrayList();
public Button QuestionButton;
public GameObject QuestionUI;
public Text QuestionText;
void Start(){
StartCoroutine(PresentQuestion());
}
IEnumerator PresentQuestion(){
CurrentQuestion = "How many times do we have to do this to make it work?";
Answers.Add ("1");
Answers.Add ("2");
Answers.Add ("3");
Answers.Add ("4");
float newY = 80.0f;
foreach(string answer in Answers){
newY-=65.0f;
string locanswer = answer;
Button btn = Instantiate(QuestionButton);
btn.transform.position = new Vector3(225, newY, 0);
btn.transform.SetParent(QuestionUI.transform, false);
btn.gameObject.SetActive(true);
btn.transform.FindChild("Text").GetComponent<Text>().text = locanswer;
btn.onClick.AddListener(() => AnswerClicked(locanswer));
}
QuestionText.text = CurrentQuestion;
return null;
}
void AnswerClicked(string value){
print (value);
}
}
I had the same issue and I found that setting the onClick listener in a separate method worked for me.
Here's how I would do it in this case:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class Testing : MonoBehaviour {
public string CurrentQuestion;
public ArrayList Answers = new ArrayList();
public Button QuestionButton;
public GameObject QuestionUI;
public Text QuestionText;
void Start(){
StartCoroutine(PresentQuestion());
}
IEnumerator PresentQuestion(){
CurrentQuestion = "How many times do we have to do this to make it work?";
Answers.Add ("1");
Answers.Add ("2");
Answers.Add ("3");
Answers.Add ("4");
float newY = 80.0f;
foreach(string answer in Answers){
newY-=65.0f;
Button btn = Instantiate(QuestionButton);
btn.transform.position = new Vector3(225, newY, 0);
btn.transform.SetParent(QuestionUI.transform, false);
btn.gameObject.SetActive(true);
btn.transform.FindChild("Text").GetComponent<Text>().text = locanswer;
SetButtonOnClick(btn, answer);
}
QuestionText.text = CurrentQuestion;
return null;
}
void SetButtonOnClickAnswer(Button button, string value){
button.onClick.AddListener(() => AnswerClicked(value));
}
void AnswerClicked(string value){
print (value);
}
}
(Disclaimer: I haven't tested this but I am running a very similar code in my project and this solved the issue.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With