#Passing the Button in Button.onClick.AddListener?

1 messages · Page 1 of 1 (latest)

fallen atlas
#

Hi!

I am making a system where I can have a group of buttons, and when one is clicked it should become uninteractable, and the others become interactable again (basically, only one button can be "selected" at once).

The problem is that I get an error when clicking one of the buttons (see attached image). It's on line 25: "btns[_btnClickedIndex].interactable = false;"

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

public class ButtonGroup : MonoBehaviour
{
    [SerializeField] private Button[] btns;

    private void Start()
    {
        for (int i = 0; i < btns.Length; i++)
        {
            btns[i].onClick.AddListener(() => { ButtonInGroupClicked(i); });
        }
    }

    public void ButtonInGroupClicked(int _btnClickedIndex)
    {
        for (int i = 0; i < btns.Length; i++)
        {
            btns[i].interactable = true;
        }

        btns[_btnClickedIndex].interactable = false;
    }
}
cedar gorge
#

try debugging the _btnClickedIndex you recieve

#

it'll be btns.Length

#

the lambda you have is capturing a reference to the variable i, rather than just its value
when the lambda is actually called, it gets what i currently is - the value at the end of the loop, btns.Length, the value that causes the loop to exit

#

you need to introduce an intermediate variable that doesn't change to be captured instead

#
    private void Start()
    {
        for (int i = 0; i < btns.Length; i++)
        {
+           int idx = i;
-           btns[i].onClick.AddListener(() => { ButtonInGroupClicked(i); });
+           btns[i].onClick.AddListener(() => { ButtonInGroupClicked(idx); });
        }
    }
fallen atlas
#

Oh okay. So a public array of indices?

#

I see, okay. I'll try

cedar gorge
#

not sure how that comes in

#

(also you can name the intermediate variable anything you want of course)

#

btw - if you only have a single statement in a lambda, you can omit the {} as a shorthand, so like () => ButtonInGroupClicked(idx) (you also don't need the semi since it's not in a separate scope)