# What is the easiest way to find a child?

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

public class SavedGamesSlots : MonoBehaviour
{
public GameObject saveSlotPrefab;
public float gap;

private Transform slots;
private string[] imagesToLoad;

// Start is called before the first frame update
void Start()
{
int counter = 0;

imagesToLoad = Directory.GetFiles(Application.dataPath + "/screenshots", "*.png");
slots = GameObject.FindGameObjectWithTag("Slots Content").transform;

for (int i = 0; i < imagesToLoad.Length; i++)
{
var go = Instantiate(saveSlotPrefab);
go.transform.SetParent(slots);

Texture2D thisTexture = new Texture2D(100, 100); //NOW INSIDE THE FOR LOOP
string fileName = imagesToLoad[i];
byte[] bytes = File.ReadAllBytes(fileName);
thisTexture.LoadImage(bytes);
thisTexture.name = fileName;

go.GetComponent<RawImage>().texture = thisTexture;

// Here to assign the fileName to the go(saveSlotPrefab) Text child

counter++;
}
}

// Update is called once per frame
void Update()
{

}
}


This screenshot show example of fileName content :

And this screenshot show the part of the file name I want to extract and assign to the text :

And this screenshot show how the prefab/s are built the Text I want to assign to the file name part is the second child of the prefab. This prefab is the prefabs I'm Instantiating (saveSlotPrefab)

• I assume you considered GetComponentInChildren? Where did you run into trouble applying this to your use case? – DMGregory Jan 28 at 2:08

## 2 Answers

GameObject.Find will search for a GameObject in the scene. To search a GameObject for a child, use Transform. Here is how I do it:

transform.Find("childname")


I found that from here.

• but is it a good thing to call Find so many times inside the loop ? – user1196715 Jan 28 at 2:13
• @user1196715 I mean, you could just call it from start by declaring a GameObject with this definition in Start, but this should work and shouldn’t cause issues. – OKprogrammer Jan 28 at 2:17

To answer the original question, as @DMGregory pointed out, typically the best/fastest way to find a child during runtime is using the GetComponentInChildren() or GetComponentsInChildren(). This isn't exactly the fastest solution in the world, but it works much better than searching by GameObject name, although honestly in most cases it probably wont be much of an issue. The main draw back to this approach is if you have two components of the same type as child, for example a Text component a players current HP and another for their MP/name/exp/whatever.

In your case I would recommend adding some helper scripts as well to make things easier to use/find:

public class SaveSlotUi : MonoBehaviour
{
// Assign these in the prefabs inspector
public RawImage saveImage;
public Text filePathText;
public Text saveFileNameText;
}

public class SavedGamesSlots : MonoBehaviour
{
public GameObject saveSlotPrefab;
public Transform slots; // why search if you can assign in the Editor
public float gap;

private Transform slots;

// Start is called before the first frame update
void Start()
{
// Counter is same as for loops "i" and is unused
// We only use this once so why keep it stored
string[] imagesToLoad = Directory.GetFiles(Path.Combine(Application.dataPath, "/screenshots"), "*.png");

for (int i = 0; i < imagesToLoad.Length; i++)
{
var go = Instantiate(saveSlotPrefab);
go.transform.SetParent(slots);

SaveSlotUi slotUi = go.GetComponent<SaveSlotUi>();
ui.saveImage.texture = LoadTexture(imagesToLoad[i]);
ui.filePathText = imagesToLoad[i];
ui.saveFileNameText = Path.GetFileName(imagesToLoad[i]);
}

// this is a pretty helpful helper function, you may want to bring this out later to a static class so anyone can use it on demand
private Texture2D LoadTexture(string path)
{
Texture2D thisTexture = new Texture2D(2, 2);
byte[] bytes = File.ReadAllBytes(path);
thisTexture.LoadImage(bytes);
thisTexture.name = path;
return thisTexture;
}
}
}