- Home /
The question is answered, right answer was accepted
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[i].ToString();
newBut.GetComponent<Button>().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
Answer by Fluffy_Kaeloky · Dec 16, 2016 at 12:53 PM
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 ?
Thanks @Fluffy_$$anonymous$$aeloky . But you are here adding a fixed piece of code to your button. I'm trying to add a call to a function on a specific GameObject. Just as one could do with the editor functionality of the button
Thanks, I did no know that it was normal that the editor was not showing the event properly. I'll test that when @home
Ok... I feel stupid... The script originally posted worked... I just had an on mouse click event to toggle the pannel with the buttons depending on what GO the raycast hit. I thought that even if the raycast would cause the panel (and thus the buttons) to disapear would occur but that the click event on the button would still trigger. Turns out it does not...
I thus just changed the click to show the panel on the right click, leaving the left click to interact with the buttons, undisturbed by my stupidity...
Thanks again for your help!