Search code examples
c#unity-game-enginelistenerunity3d-gui

Unity 5 fix Listener calls


I'm have problems using runtime-generated buttons in Unity 5. Buttons are created correctly, but i have some problem with the listeners. I use this code to create buttons:

 foreach (string str in _scene.PDF_ITEMS)
    {
        button = (GameObject)Instantiate(_primitive);
        button.GetComponent<Button>().onClick.AddListener(() => OpenPDF(str));
        button.GetComponentInChildren<Text>().text = str;
        button.GetComponent<Transform>().SetParent(this.transform, false);
        GetComponent<RectTransform>().anchorMin = Vector2.zero;
        GetComponent<RectTransform>().anchorMax = Vector2.one;
        width++;
    }

And this is the OpenPDF function:

private void OpenPDF(string name)
{
    string comandType;
    if (_scene.isCurrent(ArrayUtility.IndexOf<string>(_scene.PDF_ITEMS, name))) comandType = ControllerScene.IN_CLOSE_ITEM + "";
    else comandType = ControllerScene.IN_OPEN_ITEM + "";
    _inj.addComand(comandType, "" + (ArrayUtility.IndexOf<string>(_scene.PDF_ITEMS, name)));
}

The problem is that when i play the scene and click on a button,it is triggered the listener of the last button i have create( the function OpenPdf have as parm the last "str" value in the foreach cycle).


Solution

  • I assume your problem is related to this: Access to Modified Closure

    try to work with copy of the string

    foreach (string str in _scene.PDF_ITEMS)
    {
        string strCopy = string.Copy(str);
        button = (GameObject)Instantiate(_primitive);
        button.GetComponent<Button>().onClick.AddListener(() => OpenPDF(strCopy));
        button.GetComponentInChildren<Text>().text = str;
        button.GetComponent<Transform>().SetParent(this.transform, false);
        GetComponent<RectTransform>().anchorMin = Vector2.zero;
        GetComponent<RectTransform>().anchorMax = Vector2.one;
        width++;
    }