Start() method not getting called in 4.6 UI

My simple label in 4.6 UI:

40450-untitled2.png

It has some text, shadow and some additional behaviour.

My code to change text:

40451-untitled.png

As such, code doesn’t work because Start() method never gets called but if I move GetComponent call in setText method, everything works fine. This Text is instantiated and nested under Canvas GameObject on fly. Does it matter?


EDIT: Since there were some misinterpretations of my question, I’m going to get a bit more into details. Firstly, the text I’m talking about is a prefab (can’t add more than 2 images, here’s imgur link). As you can see, Text and Script components are on the same object and Text isn’t null if I request it in setText method like this

public void setText(int wave)
{
    label = GetComponent<UnityEngine.UI.Text>();
    label.text = "Wave " + wave;
}

so I know it exists. There’s also no class disambiguation because I defined Text with full namespace. I know Start() never gets called because I put Debug.Log and breakpoint in that method and neither worked.

There was also a question about instantiation… I do it like this

            waveLabel = (GameObject)Instantiate(waveLabelPrefab, Vector3.zero, Quaternion.identity);
            waveLabel.transform.SetParent(canvas.transform);
            waveLabel.GetComponent<WaveLabelBehaviour>().setText(waveManager.waveNum);

where canvas is

    canvas = GameObject.Find("Canvas");

The result in hierarchy is like this. Instantiation is done in response to gameplay, eg. button click.

When I came back and read you comments, I tried something else and hold on your pants because things got crazy real fast.

This code triggers breakpoint set at line Debug.Log and it also outputs to console

Text label;
void Start()
{
    Debug.Log("Start");
}

public void setText(int wave)
{
    label = GetComponent<Text>();
    label.text = "Wave " + wave;
    GetComponent<RectTransform>().localPosition = Vector3.zero;
}

while this doesn’t run Start() method and it throws exception about label being null.

Text label;
void Start()
{
    Debug.Log("Start");
    label = GetComponent<Text>();
}

public void setText(int wave)
{
    label.text = "Wave " + wave;
    GetComponent<RectTransform>().localPosition = Vector3.zero;
}

What is mind-boggling is that GetComponent() prevents Start() method from being called.

“This Text is instantiated and nested under Canvas GameObject on fly”

When is it instantiated? During a Start call? Then that might happen after this Start method is called.

Now, the fast hack is to move the instantiation of the Text box to an Awake call instead. That’s probably bad. Better would be to just go fetch the Text the first time you need it:

public void SetText(int wave) {
    if(label == null)
        label = GetComponent<Text>();

    label.text = "This should work";
}

Ah the benefit of actually having Unity to test this:

OK you can choose whichever method you want to order when it calls the script, for the record I used the method I suggested first Edit → Project Settings → Script Execution Order

40461-scriptexecutionorder.png

As much to make sure I wasn’t talking rubbish. InstObj instantiates and UpdateObj alters the text.

I instantiated it onto a ParentPanel, and it failed. No matter which way I tried it. Then it struck me the code is actually wrong as UI elements can be quite complex so you have to go down another level. This works though:

	Text label;


	// Use this for initialization
	void Start () {
		label = GetComponentInChildren<Text>();
	}

Put that script on the Panel/Canvas and try again. It’s the GetComponentInChildren that finally got it working. Although altering the order to UpdateObj first does break it again.

I worked my way around this by making a public void Setup() function in my UI and calling it from a sort of GameMaster type script’s Awake(). This way it is being called before Start().

The problem was my UI. GameMaster was trying to add things to it, but the FindChild allocations in the UI Awake () were not calling, returning null references.

Why passing through a separate Awake gets it to go before Start, or rather why the heck it wouldn’t run before Start on its own remains a mystery to me.