0
\$\begingroup\$

I've got a problem and I am struggling with this for a couple of days now.

I am making an Editor script and I want to access buttons individually when created by a for loop. There is a public class ButtonNode which stores some variables of the button like name and size.

public class ButtonNode
{
    public bool button;         
    public string name = "O";
    public float sizeW = 25f;

    public void AlterButton()
    {
        name = "P";
    }
}

Then there is my Editor script in which I create the buttons. This is where I get stuck, how do I access these buttons individually? For example, I want to change the name of the button when that button is clicked. How do I do that? Because they are booleans (I don't really know why, this is the legacy GUI) I can't access the transform.name components etc).

public static ButtonNode[] bn = new ButtonNode[10];

void OnGUI()
{
    GUILayout.BeginHorizontal();

    for (int i = 0; i < bn.length; i++)
    {
        bn[i] = new ButtonNode();
        if (bn[i].button = GUILayout.Button(bn[i].name + i, GUILayout.Width(bn[i].sizeW)))
        {
            bn[i].AlterButton();
        }
    }

    GUILayout.EndHorizontal();
}
\$\endgroup\$
6
  • 1
    \$\begingroup\$ You are recreating your ButtonNode objects each time, the OnGUI function is being called. You will certainly want to create them inside OnEnable or at another point, to avoid overwriting the current buttons. \$\endgroup\$ Commented Mar 2, 2016 at 16:02
  • \$\begingroup\$ If I am running this at startup for example, I still can't access individual buttons. Any idea how to do that? \$\endgroup\$
    – Patrick
    Commented Mar 3, 2016 at 18:41
  • \$\begingroup\$ In which way do you want to access them? If you want each button to execute different tasks, you probably have to look for another approach. If you just want to change the name of each button from 'O' to 'P', then this should work. \$\endgroup\$ Commented Mar 3, 2016 at 19:16
  • \$\begingroup\$ I think we are on the right track, I noticed that my startup wasnt really one frame, but still ran multiple times so they are still being recreated everytime. I can't think of a good way to only run this once, though. They are visible when I create them every frame, but when I am creating the buttons once with a boolean they are not visible. \$\endgroup\$
    – Patrick
    Commented Mar 3, 2016 at 19:49
  • \$\begingroup\$ You can remove the initialization and set bn = null. You then check in OnGUI if bn == null and create the array and all buttons. The code should then look similar to this \$\endgroup\$ Commented Mar 3, 2016 at 20:38

1 Answer 1

0
\$\begingroup\$

You are recreating your ButtonNode objects each time, the OnGUI function is being called. You will certainly want to create them at a single point in your application.

You can remove the initialization and set bn = null. You then check in OnGUI if bn == null and create the array and all buttons. The code should then look similar to this:

public static ButtonNode[] bn = null;

void OnGUI()
{
    GUILayout.BeginHorizontal();

    if (bn == null)
    {
        bn = new ButtonNode[10];
        for (int i = 0; i < bn.Length; ++i)
        {
            bn[i] = new ButtonNode();
        }
    }

    for (int i = 0; i < bn.length; i++)
    {
        // this line has to be removed, to avoid recreation of buttons
        // bn[i] = new ButtonNode();
        if (bn[i].button = GUILayout.Button(bn[i].name + i, GUILayout.Width(bn[i].sizeW)))
        {
            bn[i].AlterButton();
        }
    }

    GUILayout.EndHorizontal();
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .