-1
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class GenerateUIButtons : MonoBehaviour
{
    public GameObject buttonPrefab;
    public GameObject parent;
    public int numberOfButtons;
    public float spaceBetweenButtons;

    private Button[] buttons;

    // Start is called before the first frame update
    void Start()
    {
        buttons = new Button[7];

        for (int i = 0; i < Rotate.names.Length; i++)
        {
            GameObject newButton = Instantiate(buttonPrefab);
            newButton.name = Rotate.names[i];
            newButton.transform.SetParent(parent.transform, false);
            buttons[i] = newButton.GetComponent<Button>();
            buttons[i].onClick.AddListener(() => ButtonClicked(i));
        }
    }

    void ButtonClicked(int buttonNo)
    {
        Debug.Log("Clicked On " + buttons[buttonNo]);
    }

    // Update is called once per frame
    void Update()
    {

    }
}

I'm getting exception on the line :

Debug.Log("Clicked On " + buttons[buttonNo]);

IndexOutOfRangeException: Index was outside the bounds of the array

What I want to do is when I click on one of the buttons it will do the same action inside ButtonClicked.

Daniel Lip
  • 3,867
  • 7
  • 58
  • 120
  • 2
    can you add a `Debug.Log(buttonNo);` right before it or use Breakpoints? – derHugo Jun 07 '19 at 11:24
  • 1
    and .. are you sure `Rotate.names.Length` is always `7`? why instead of hardcoding not rather use `buttons = new Button[Rotate.names.Length];`? – derHugo Jun 07 '19 at 11:25
  • 1
    Actually I would simply pass on the Button reference directly like `buttons[i].onClick.AddListener(() => ButtonClicked(newButton));` and do `void ButtonClicked(Button button) { Debug.Log("Clicked On " + button); }` . And as a tip: If yu change the type of the prefab directly to `public Button buttonPrefab;` you don't need to use `GetComponent` – derHugo Jun 07 '19 at 11:27
  • Possible duplicate of [UI button listener AddListener not working in a loop](https://stackoverflow.com/questions/43635608/ui-button-listener-addlistener-not-working-in-a-loop) – Hellium Jun 07 '19 at 11:30

1 Answers1

2

This is a closure problem, don't use the loop value to create a closure, assign the value to another local variable first.

for (int i = 0; i < Rotate.names.Length; i++)
{
    ...
    int j = i;
    buttons[i].onClick.AddListener(() => ButtonClicked(j));
}
shingo
  • 18,436
  • 5
  • 23
  • 42