所以我有一个脚本(Unity C#)运行一个IEnumerator函数,它生成一个答案数组,我想以列表格式呈现它们。
所以我用:
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);
}
QuestionButton是我在检查器中链接的按钮游戏对象,它实例化正常,文本设置正常,但是当我添加监听器时。
当我点击按钮时,我会在循环中获得最后一个字符串或_answer&#34;每次&#34;。
我不确定为什么每个实例化的新Button(btn)对象都不会在AnswerClicked上获得自己的Listener。有人可以解释一下吗?
仅供参考:QuestionUI是我的画布。
感谢。
更新:
此代码有效,但我之前的问题仍然存在。我将尝试使用我的实际代码进行更新。
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);
}
}
答案 0 :(得分:2)
我遇到了同样的问题,我发现在单独的方法中设置onClick监听器对我有用。
以下是我在这种情况下的表现方式:
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);
}
}
(免责声明:我没有对此进行测试,但我在项目中运行的代码非常相似,这解决了这个问题。)
答案 1 :(得分:1)
不确定这个问题是否太老而无法回答。
我遇到了同样的问题,这就是我为使代码工作所做的事情:
这两个步骤都很重要,如果你只做其中一个步骤,那就不行了。
答案 2 :(得分:0)
好的,所以我从IEnumerator函数中删除了实例化然后回答,奇怪的是它开始工作了。
我最终得到了类似的东西:
// Use this for initialization
void Start () {
QuestionUI.SetActive (false);
StartCoroutine(PresentQuestion ());
}
IEnumerator PresentQuestion(){
CurrentStage = Stage.QuestionStart;
CurrentQuestionCard = Instantiate (QuestionCard);
CurrentQuestionCard.GetComponent<QuestionCard> ().MoveCardToPosition (QuestionSlot);
yield return new WaitForSeconds(3);
ShowQuestion ();
}
void ShowQuestion(){
QuestionUI.SetActive (true);
QuestionUI.SetActive (true);
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);
}
答案 3 :(得分:0)
这就是我遇到同样问题时我的代码所做的工作。 (尝试根据一些GameObjects列表创建一组按钮,这些游戏对象是某些父GameObject的子节点,其中每个按钮在执行此创建的脚本时单击时会响应一些函数,其中一个参数引用它应该工作的对象用。)
将“foreach”循环更改为常规for循环。如下所示:
for(int i=0;i<here.transform.childCount;i++)
{
Transform child = here.transform.GetChild(i);
Button new_button = (Button) Instantiate(bCharacter,transform.position,transform.rotation);
new_button.GetComponentInChildren<Text>().text = child.name;
new_button.transform.SetParent(panel_people.transform,false);
new_button.onClick.AddListener( () => LookAtObject(child.gameObject) );
}
我很生气,我不知道为什么这个改变有效,使它成为伏都教解决方案,但它确实解决了每个具有正确名称的按钮的相同问题,但反应好像链接到最后一项集。
答案 4 :(得分:0)
我明白了。如果您正在为该按钮添加父级的游戏对象上没有“Canvas Renderer”组件,则该按钮将不起作用。只需将一个画布渲染器添加到按钮的父游戏对象中,它就可以使用
button.onClick.AddListener(() => MyMethod(myArg));