4.6 adding onClickListener to instatiated buttons on a canvas

Ok let me try to explain: I am trying to generate a menu trough a script so everything (canvas and buttons included) will be instatiated, i have succesfully used prefabs for the canvas with some images and the generic buttos i need, even setting text to the buttons. However i cannot set the listener to each button i create so I’m stuck. Here is the code i have:

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class CrearMenu : MonoBehaviour {

	public GameObject prefabButton;
	public int numberOfObjects = 10;
	public float radius = 5f;
	
	public GameObject canvasMenu;
	private GameObject canvasMenuPa;


	void Start() {
		canvasMenuPa = (GameObject) Instantiate(canvasMenu);
		
		for (int i = 0; i < numberOfObjects; i++) {
			
			Vector3 pos = new Vector3(i*50, i*7, 0);
			GameObject boton;
			boton = (GameObject) Instantiate(prefabButton);

			boton.transform.SetParent(canvasMenuPa.transform, false);

			//setting the label
			Text[] datext; 
			datext = boton.GetComponentsInChildren<Text>();
			datext[0].text = "level # ";

			boton.GetComponent<RectTransform>().localPosition = pos;
			boton.GetComponent<Button>().onClick.RemoveAllListeners();
			boton.GetComponent<Button>().onClick.AddListener(() => MyMethod(i));

			//this didnt work either
//			boton.GetComponent<Button>().onClick.AddListener(delegate() {
//				//removebutton(this);
//				//print ("presed!!!!!!!!!!!!!!!!");
//				MyMethod(i);
//			});
		}
	}

	void MyMethod(int i){
		//do something
		print ("BUTTON PRESSED");
	}
}

I don’t know if I’m missing something but any help would be appreciated. This is also kinda getting on my nerves because i have seen several examples using identical code which seems to work fine.

I’ve got a video tutorial here.

Without an exact description of your problem I’m picking the listeners are all calling the method with the same argument? Key point on the listener is that you need a local scope variable, you can’t use i as it keeps changing.

int index = i;
boton.GetComponent<Button>().onClick.AddListener(() => MyMethod(index));

You may also need to play with the brackets on your lambda expression. If it doesn’t work as above try the following.

boton.GetComponent<Button>().onClick.AddListener(() => {MyMethod(index);});

If neither of these work please post back with an exact description of what is going wrong. Or watch my video above, it takes you through step by step how to build the menu and add listeners.

‘boton’ is local variable in your code.

Try to

private GameObject boton;

for (iterator = 0; iterator < levelToChoose; iterator++)
{
//gameObject.Find(“EINZIGARTIG”).GetComponent(Text).text = “HostList”;

	myLevelObject =  Instantiate(serverLevelToChoose);
	myLevelObject.transform.SetParent(GameObject.Find("MultiPlayerLevelSelect").transform,false);
	myLevelObject.transform.Find("Text").GetComponent(Text).text = "Level " + (iterator+1);
	myLevelObject.transform.Find("Level").GetComponent(Text).text = "Level" + (iterator);	
	
  	;
  	myLevelObject.GetComponent(RectTransform).transform.localPosition.z = 0;
	
  //hostButton.transform.parent = GameObject.Find("GameSelect").transform;
  	myLevelObject.transform.localScale = Vector3.one;
  	myLevelObject.name =  "Level" + iterator;
  	
  	var level = myLevelObject.transform.Find("Level").GetComponent(Text).text
  	
  	var myIterator = iterator;
  	
	myLevelObject.GetComponent(Button).onClick.AddListener(function() {
 	
 		myLevelObject.transform.Find("Text").GetComponent(Text).text = "VERBINDE AB JETZT" + iterator;      	
 		Debug.Log (level);
 		
 		//THIS VARIABLE ALWAYS GIVES 3 BACK INSTEAD OF 0,1,2,3! 
 		Debug.Log (myIterator);
  		serverChooseLevel(level);
  	});

}

This is my Code. In my opinion everything is nearly the same as in your youtube video. Outside of the funcion i declared myLevelObject as a private var GameObject. But still when i click on the button ist gives me the Variable of Button 3 and no 0,1 or 2. Any ideas?

thank u for your question u help me to solve some thing heheh
by the way the best to solve your problem is simple to make the prefap as button
and Instantiate button

Button boton;
boton = (Button)Instantiate(buttonprefap);

then after that :

boton.onClick.RemoveAllListeners();
boton.onClick.AddListener(() => MyMethod(1));

you dont need to use the getcomponent because its seem have bug in unity 5

Hi

         boton.tag = i;
         boton.GetComponent<Button>().onClick.AddListener(() => MyMethod(boton.tag));

it Works !!