AddListener function not working?

I’m trying to add an event to a procedurally generated button, using the following script;

Transform purchaseButton = newItem.transform.FindChild("Purchase");
		if (purchaseButton != null) {
			Debug.Log("found button");
			purchaseButton.GetComponent<Button>().onClick.AddListener(delegate {btnClicked("testarg"); });
		}

public void btnClicked(String param) {
	Debug.Log ("button clicked: " + param);
}

Unfortunately, it looks like this isn’t being updated at all in the game object - clicking into it via the unity interface doesn’t show any update on the button function, nor does the button itself call the method I’ve passed through via the AddListener function.

Can anyone lend me a hand with this?

Here is what I did. I had a prefab button I want to Instantiate and then addListener, but what I did was add the listener to the prefab and not to the clone I just Instantiated.

public GameObject prefab; //prefab you want to Instantiate

public GameObject obj; //the Instantiated clone

void Start(){
	obj = Instantiate(prefab, parent)
	obj.GetComponent<Button>().onClick.AddListener((delegate { yourMethod();)); //or the lambda way (() => {yourMethod();})
	
	//mistake I made
	
	prefab.GetComponent<Button>().onClick.AddListener(delegate stuff) //this is what caused my problem.
}

I got to fancy with naming variables and should have used simpler names like obj and prefab.

Transform purchaseButton = newItem.transform.FindChild(“Purchase”);
if (purchaseButton != null) {
Debug.Log(“found button”);
UnityEngine.Events.UnityAction action1 = () => { this.btnClicked(“testarg”); };
purchaseButton.GetComponent().onClick.AddListener(action1);
}

 public void btnClicked(String param) {
     Debug.Log ("button clicked: " + param);
 }

This will not be displayed on editor but still works

I also ran into this issue. Somehow, I unchecked the Raycast target on the image script. Checking this allowed the onClick.AddListener() to work.

.onClick.AddListener(() => TestAddition());

private void TestAddition()
{
Debug.Log(“Testing Button”);
}

Hi there!

I have one solution for someone who encounters the same sort of the problem.

If you want to create Prefab of game object, which will contain button or buttons as components of parent itself, or inside of his childrens, and you want to initiate it’s Listeners with onClick = () => { someDelegate}; And then instantiate them and catch their Listeners all finely working.

Just add this method:
GameObject InstantiateWithListeners

GameObject InstantiateWithListeners(GameObject prefab, Transform parentTransform)
{
 GameObject instance = GameObject.Instantiate(prefab, parentTransform) as GameObject;
 if (instance.GetComponent<Button>() != null)
      instance.GetComponent<Button>().onClick = prefab.GetComponent<Button>().onClick;
}

And use it instead of usual GameObject.Instantiate();
So now you can use:

GameObject m_somePrefab;
Transform m_parentTransform;
void Start()
{
 m_somePrefab.GetComponent<Button>().onClick = () => { Debug.Log("Hello there!"); };
}

GameObject InstantiateSomePrefab()
{
 GameObject instance = InstantiateWithListeners(m_somePrefab, m_parentTransform) as GameObject;
 return instance;
}

By the way, to get Button component in child or set a bunch of buttons, I will recommend you to create simple MonoBehaviour component on parent game object and add to him public List of Buttons. After that, Initiate this prefab with all needed button components in inspector. Now you can easily iterate on every matching Button component inside InstantiateWithListeners method and initiate it with proper Listener as was shown above.

First, don’t use Transform.FinsChild, it is deprecdated, you can look straight for a button component in a child.
Second, use simple lambda function if you want to pass a parameter to other methos.

...
Button purchaseButton = newItem.GetComponentInChildren<Button>();
if (purchaseButton != null)
{
    Debug.Log("found button");
    purchaseButton.onClick.AddListener(() =>
    {
        BtnClicked("testarg");
    });
}
...

public void BtnClicked(string param)
{
    Debug.Log("button clicked: " + param);
}

The previously listed solutions didn’t seem to work for me, so here is what I came up with.

My problem anyway seemed that it tried to add the listener after the button was pressed and by that time, the variables used in the button would have changed.

So I made a new script that was on the Button Prefab, so I can add the function in the prefab.
And when I created the Button prefab, I only need to change the variables in the script instead of changing the button.

script on the Prefab where the Button is on:
public int i;
public MonoBehaviour mon;
public void ButtonPressed()
{
mon.function(i);
}

script where I instantiate the button:

GameObject obj = Instantiate(Prefab, Transform);
ButtonFunction b = obj.GetComponent();
b.mon = this;
b.i = variable;