How to access Text component on canvas when multiple present?

From a script on my player I am trying to access a text component on my canvas. However there are two text components on it (two children), each with a different name.

First I tried:

Text text = GameObject.FindGameObjectWithTag("MainCanvas").GetComponentInChildren<Text>();

But sadly enough this only returns the first child that has a text component. So if I get them in a different order, a different one is returned.

I tried a ton of things and then went all out and wrote:

Text targetText

void Start ()
{
    GameObject[] textGOs = GameObject.FindGameObjectWithTag("MainCanvas").GetComponentsInChildren<GameObject>();
    foreach(GameObject go in textGOs)
    {
        if(go.name == "TargetText")
        {
            targetText = go.GetComponent<Text>();
        }
    }
}

The idea being: find the canvas, find all children game objects, find the one that has the correct name, and then assign its text component. This also didn’t work however because of the following error:

ArgumentException: GetComponent requires that the requested component
‘GameObject’ derives from
MonoBehaviour or Component or is an
interface.

So I googled and what I understand is that Text does not derive from Monobehaviour and thus can not be used this way.

Now I am completely in the dark on how to do this.

So the question is: How do I access one of the same components with different names that are all attached to a canvas, from a script on something else?

And note that I have a canvas with two children and each child has a text component. I want the one that is named “blabla”. The script is on a completely different game object.

You misread the error, Text does inherit from MonoBehaviour (you would not be able to add it in the inspector if it did not). But the error says that GameObject does not, and it actually does not indeed.

  GameObject[] textGOs = GameObject.FindGameObjectWithTag("MainCanvas").GetComponentsInChildren<GameObject>();

You are trying to find all GameObject component but no possible.

You say your two objects containing the Text component have different names so you can do:

  GameObject canvasObject = GameObject.FindGameObjectWithTag("MainCanvas");
  Transform textTr = canvasObject.transform.Find("ObjectName");
  Text text = textTr .GetComponent<Text>();

if the object is not on the first layer of children, that is you have your canvas and then a child object and as a child of this, you have your object with the text, just provide the full path t it:

Transform textTr = canvasObject.transform.Find("FirstLayerName/ObjectNameWithText");

You could iterate throught the child gameobjects and check their names.

Canvas mCanvas;
Text targetText;

void Start(){
	mCanvas = GameObject.FindGameObjectWithTag("MainCanvas");
	for (int i = 0; i < mCanvas.transform.childCount; i++){
	        GameObject child = mCanvas.transform.GetChild(i).gameObject;
		if (child.name == "whatever") {
			targetText = child.GetComponent<Text>();
		}
	}
}

haven’t tested it but it should work