5
\$\begingroup\$

Given a Canvas test_canvas containing a Button test_button and an empty GameObject that manages instantiation and scripts and the like called test_manager, what are the steps to instantiate this button through code as opposed to having it already there?

I've tried making the button a prefab and instantiating it as I would any other object but that didn't work. I tried making the canvas a prefab and then trying the button but nothing. I've searched around for quite some time and there's mention of RectTransform and SetParent but steps or specific details would clear up my confusion

\$\endgroup\$
2

4 Answers 4

6
\$\begingroup\$

Prefab your Canvas and a Button and add this script to the test_manager gameobject

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

public class TestManagerScript : MonoBehaviour {
public GameObject canvas;
public GameObject button;

    void Start () {
        GameObject newButton = Instantiate(button) as GameObject;
        newButton.transform.SetParent(newCanvas.transform, false);
    }
}

be sure to drag the prefab button and prefab canvas to the public field slots this creates on the test_manager gameobject.

If you are also Instantiating the canvas you want to keep in mind that the UI will display from top to bottom as it is listed in the hierarchy. So you would want something like this.

 void Start () {

        GameObject newCanvas = Instantiate(canvas) as GameObject;
        GameObject newButton = Instantiate(button) as GameObject;
        newButton.transform.SetParent(newCanvas.transform, false);
    }
\$\endgroup\$
3
\$\begingroup\$

You may want to do something like this if you don't want to use prefabs.

public void CreateButton(Transform panel ,Vector3 position, Vector2 size,  
UnityEngine.Events.UnityAction method)
{
    GameObject button = new GameObject();
    button.transform.parent = panel;
    button.AddComponent<RectTransform>();
    button.AddComponent<Button>();
    button.transform.position = position;
    button.GetComponent<RectTransform>().SetSize(size);
    button.GetComponent<Button>().onClick.AddListener(method);
}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ error CS0311: The type 'Button' cannot be used as type parameter 'T' in the generic type or method 'GameObject.AddComponent<T>()'. There is no implicit reference conversion from 'Button' to 'UnityEngine.Component'. \$\endgroup\$ Commented Apr 24, 2020 at 22:47
  • \$\begingroup\$ This answer is almost 5 years old and I haven't worked with Unity in a long time. There is a possibility that the Unity API has changed since then. If you find a working solution please update this answer. Or let me know and I will update it :) \$\endgroup\$
    – Umair M
    Commented Apr 25, 2020 at 15:48
1
\$\begingroup\$

Unity provides a built-in API call that makes this easy:

GameObject newButton = DefaultControls.CreateButton( new Resources() );

...you can then customize it by calling:

Button buttonComponent = newButton.GetComponentInChildren<Button>();
... // do things with the Button here.

Old, but still a top hit on Google, so ...

\$\endgroup\$
2
  • \$\begingroup\$ error CS1503: Argument 1: cannot convert from 'UnityEngine.Resources' to 'UnityEngine.UI.DefaultControls.Resources' \$\endgroup\$ Commented Apr 24, 2020 at 22:08
  • \$\begingroup\$ That's a bug in your code - your IDE should have automatically resolved this for you. Copy/paste the second '....Resources' section into the code I gave where it says "Resources". The compiler is literally saying it doesn't know which "Resources" class you mean, and is simply asking you to specify. Or install a better IDE. It should be doing this automatically and giving you a popup to let you decide. \$\endgroup\$
    – Adam
    Commented Apr 26, 2020 at 0:14
0
\$\begingroup\$

Create a Ui Button at runtime, Working example without prefabs.

    public static UnityEngine.UI.Button UiTexturedButton(Sprite sprite, Vector2 size, GameObject canvas)
    {
        GameObject go = new GameObject("Textured button (" + sprite.name + ")");

        Image image = go.AddComponent<Image>();
        image.sprite = sprite;

        UnityEngine.UI.Button button = go.AddComponent<UnityEngine.UI.Button>();
        go.transform.SetParent(canvas.transform, false);

        image.rectTransform.sizeDelta = size;

        return button;
    }
\$\endgroup\$

You must log in to answer this question.

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