Button AddListener during runtime pointing to another GameObject?

Hi all,

I’m trying to create buttons during runtime and point ‘OnClick’ event to function on a component on another GameObject.

Simple view of my bit of code:

int yPos = -60;
Active active = hit.transform.GetComponentInParent<Active>();
for (int i = 0; i < active.allowedCraft.Length; i++)
{
	GameObject newBut = Instantiate(Resources.Load("Button"), new Vector3(0,0,0), Quaternion.identity) as GameObject;
	newBut.transform.parent = machineTipGroup.transform; //machineTipGroup is a UI panel with a canvas group component
	newBut.transform.localPosition = new Vector3(0,yPos,0);
	yPos +=30;
	newBut.GetComponentInChildren<Text>().text = active.allowedCraft*.ToString();*
  • newBut.GetComponent().onClick.AddListener(() => active.ChangeRecipe());*
    }
    No error is thrown by Unity, but the buttons created do not contain any OnClick event.
    ‘hit.transform.gameObject’ is not the object on wich this script is attached to.
    ‘ChangeRecipe()’ is public and present in component attached to hitted transform GO.
    First time adding buttons during runtime, searched on UA and others but did not find a working solution.
    Thanks for your help and time
    EDIT: code is clearly not fine-tuned for performance. Was just a ‘make it work first THEN make it work nicely’ approach

I just tested it with Unity 5.4.1 with a similar piece of code :

    public GameObject prefab = null;

    public void Start()
    {
        GameObject instance = GameObject.Instantiate(prefab);
        instance.transform.SetParent(transform, false);

        Button butt = instance.GetComponent<Button>();

        butt.onClick.AddListener(() => { Debug.Log("Clicked !"); });
    }

It works just fine. For the OnClick Event in the UI not showing, that’s normal. The only thing I can think of is checking your active variable and code, there must be something wrong.
Also, try writing a log in your lambda, just to be certain that the event is fired.

Edit : I just realized that I have very poor choice in variable names.

Edit2: I tested it with a new piece of code :

public class ButtonInstantiate : MonoBehaviour
{
    public GameObject prefab = null;

    public OtherScript other = null;

    public void Start()
    {
        GameObject instance = GameObject.Instantiate(prefab);
        instance.transform.SetParent(transform, false);

        Button butt = instance.GetComponent<Button>();

        butt.onClick.AddListener(() => {
            Debug.Log("Clicked !");
            other.Foobar();
        });
    }
}

and OtherScript being :

public class OtherScript : MonoBehaviour
{
    public void Foobar()
    {
        Debug.Log("Foobar has been called.");
    }
}

And it works just fine for me. Is there something I don’t understand ?