Не могу решить проблему с индексами массивов в с# в проекте в юнити

Имею следующий код. Он создает кнопки в определенном месте с данными из массива.

public void CreateItemShop()
{

    for (int i = 0; i < dataSkins.Length; i++)
    {
       
        GameObject skinItem = Instantiate(prefabItemShopUI, Content.transform);
        skinItem.transform.GetChild(3).GetComponent<Image>().sprite = dataSkins[i].icon;
        skinItem.transform.GetChild(2).GetComponent<TextMeshProUGUI>().text = "" + dataSkins[i].price;

        Button buyButton = skinItem.transform.GetChild(6).GetComponent<Button>();

        buyButton.onClick.AddListener(() => OnClickBuyButtonSkin(buyButton, i));
     
        print(dataSkins[i].name);
    }

 }

Строка print(dataSkins[i].name); выполняется нормально. Индексы выводятся в консоль правильно. Чего не могу сказать о строке buyButton.onClick.AddListener(() => OnClickBuyButtonSkin(buyButton, i)); Данный метод возвращает лишь ошибку IndexOutOfRangeException: Index was outside the bounds of the array.

   public void OnClickBuyButtonSkin(Button button, int i)
{
   
    Debug.Log(dataSkins[i].name);
    button.gameObject.SetActive(false);
}

Буду благодарен за любую помощь.


Ответы (1 шт):

Автор решения: Александр Даниловский

Классическая ошибка. Прочитайте про замыкания. В Вашем случае нужно создать переменную, присвоить ей значение итератора и передать в лямбду.

    var buttonIndex = i;
    buyButton.onClick.AddListener(() => OnClickBuyButtonSkin(buyButton, buttonIndex));

Если коротко о причине, то лямбды будут выполнены после цикла. И в это время i везде будет одинаково и равно dataSkins.Length, что является не валидным значением для индекса.

→ Ссылка