0

I have a list of Buttons that get activated after certain conditions are met. I then add a listener to each button to call a function when clicked. That function then needs to be able to get the text off the button that was clicked. This is what I've tried but it returns an out of range error, I think because it calls the function once clicked, and at that point the variable i is maxed out.

public List<GameObject> ButtonList = new List<GameObject>();
    
void Start() {
    for (int i = 0; i < ButtonList.Count; i++) {
        ButtonList[i].SetActive(true);
        ButtonList[i].GetComponent<Button>().onClick.AddListener(() => {GetButtonText(ButtonList[i]); });
    }
}

public void GetButtonText(GameObject SelectedButton) {
    Debug.Log(SelectedButton.GetComponentInChildren<TMP_Text>().text)
}

I thought about creating game objects for each button and assigning them in the inspector, but the number of buttons in the list is likely to fluctuate, so it needs to remain dynamic. Additionally, because the game object this script is attached to is a prefab, I can't set up the listeners in the inspector either.

1 Answers1

0

First of all I would suggest to make it list of Button and not a GameObjects you still will be able to access GameObject without call GetComponent each time. This think happened because it use the last value of i: you need to redo it like that:

public List<GameObject> ButtonList = new List<GameObject>();
    
void Start() {
    for (int i = 0; i < ButtonList.Count; i++) {
        var button = ButtonList[i];
        button.SetActive(true);
        button.GetComponent<Button>().onClick.AddListener(() => {GetButtonText(button); });
    }
}

public void GetButtonText(GameObject SelectedButton) {
    Debug.Log(SelectedButton.GetComponentInChildren<TMP_Text>().text)
}

Base And I rater suggest to create a class to wrap the buttons

   public class MyButton : MonoBehaviour
    {
        public event Action<int> OnClick;
        [SerializeField] private Button button;
        [SerializeField] private Text text;
        private int id = -1;

        private void Awake()
        {
            button.onClick.AddListener(Click);
        }

        private void Click()
        {
            OnClick?.Invoke(id);
        }

        public void Init(int index)
        {
            id = index;
        }

        public void SetText(string message)
        {
            text.text = message;
        }
    }