Adding a Button to a Canvas doesn't work right

I am new to Unity and I am currently trying to add a Button dynamically to a Canvas in my scene. The button is a prefab called EventButton which I add as a public variable in my script:

But when I run the game, I can see that a clone of my button is added to the scene, but it’s not visible and I get the following error:

NullReferenceException: Object reference not set to an instance of an object
GameController.MakeButtons () (at Assets/Scripts/GameController.cs:25)
GameController.Start () (at Assets/Scripts/GameController.cs:17)

Now, I have a bachelor’s degree in Computer Science so I know what the above means. But I don’t know why it happens. Below is my script:

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

public class GameController : MonoBehaviour
{
    public Canvas canvas;
    public Button buttonPrefab;

    public float xMin;
    public float xMax;
    public float yMin;
    public float yMax;

    void Start ()
    {
        MakeButtons ();
    }

    void MakeButtons ()
    {
        for (int i = 0; i < 3; i++) {
            Vector3 pos = new Vector3 (Random.Range (xMin, xMax), Random.Range (xMin, xMax),0);
            Button btn = Instantiate (buttonPrefab, pos, canvas.transform.rotation) as Button;
            btn.GetComponent<Text>().text = "" + (i + 1);
            RectTransform rect = btn.GetComponent<RectTransform>();
            rect.SetParent(canvas.transform, false);
            rect.offsetMin = Vector2.zero;
            rect.offsetMax = Vector2.zero;
        }
    }
}

I would really appreciate some help with this, as Unity is rather tricky at first glance for me.

You’re accessing the Text component on the button itself. The Text component you’re looking for is on the Text object, which is the child of your button.

Alright, so how would I go about getting the children of the Button? I haven’t been able to find a Children property or GetChildren() method. I can only find GetComponents which inconveniently gives me an old-school array. No list.

Since it is the one and only child, I would use GetChild(0). This returns the first child in the hierarchy. It is a method of the Transform component and will also return a Transform.

Also, for your example it would be:

btn.transform.GetChild(0).GetComponent<Text>().text = "" + (i + 1);

If you’re not sure of the index of the child, but you know the name you’re looking for, you can use FindChild(“GameObject Name”).

Alright thanks. That’s one part solved at least.

Now the next thing is that the buttons don’t seem to render. They are part of the Canvas now, but they don’t render and they are all three in the exact same location, however the first one have 3.814697e-06 as Y Position. That shouldn’t be possible I am pretty sure??

If you just zero out the position, not the offset, is it visible on your canvas?

Yeah if I zero out the position they show. So should I just not touch the offset and then just go with random position?

Why are you adjusting the offset? Will each button’s offset be different than the prefab’s? Look at anchoredPosition for positioning relative to your anchor.

No, I just tried to follow other examples.