0
\$\begingroup\$
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 :

fileName

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

part of the file name to get 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)

Text child is the second child in the prefab and this is the Text I want to assign to the file name part

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

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.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ but is it a good thing to call Find so many times inside the loop ? \$\endgroup\$ – user1196715 Jan 28 at 2:13
  • \$\begingroup\$ @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. \$\endgroup\$ – OKprogrammer Jan 28 at 2:17
3
\$\begingroup\$

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;
        }
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.