Download, save to disk and load a set of images. Problem with coroutines.

Hello, community!

I want to make a script that downloads some images from a WMS server, stores them in a local folder in the project and then loads them as a texture to put in some plane objects (imagine to build a map from 4 planes using images downloaded from that server).

The thing is that if the download lasts for too long, the images won`t be loaded correctly since they haven’t been saved to the local folder yet. So, I need to wait for all of those images to be loaded before the script starts to load them as textures.

The download is triggered by a click on a button.

Here´s the code:

private string savePath = "PATHTOSAVE-IGNORETHIS";

private ImageDownloader downloader;
private int tilesNumber;

private void Start()
    {
        downloader = gameObject.AddComponent<ImageDownloader>();
        tilesNumber = 4;
    }

public void UpdateLayer(string layerName, string imageURL)
    {  
        int imageIndex;

            // DOWNLOAD OF IMAGES STARTS HERE

            for (imageIndex = 0; imageIndex < tilesNumber; imageIndex++)
            {
                downloader.downloadImage(imageURL, savePath, layerName, imageIndex);
            }
 
        setLayerTexture(layerName);

    }

Methods to download and save images to disk. I think that the problem is where "yield return uwr.SendWebRequest(); is, because that coroutine stops and the Main Thread continues its work"

public void downloadImage(string url, string pathToSaveImage, string layerName, int imageIndex)
    {
        this.url = url;
        pathToSaveImage += layerName + "_" + imageIndex + ".jpg";
        StartCoroutine(_downloadImage(url, pathToSaveImage));
    }

    private IEnumerator _downloadImage(string url, string savePath)
    {
       
        UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(url);
      
        {
            yield return uwr.SendWebRequest();

            if (uwr.isNetworkError || uwr.isHttpError)
            {
                Debug.LogError(uwr.error);
            }
            else
            {
                Debug.Log("Success");
                Texture myTexture = DownloadHandlerTexture.GetContent(uwr);
                byte[] results = uwr.downloadHandler.data;
                saveImage(savePath, results);

            }
        }
    }

    void saveImage(string path, byte[] imageBytes)
    {
       
        //Create Directory if it does not exist
        if (!Directory.Exists(Path.GetDirectoryName(path)))
        {
            Directory.CreateDirectory(Path.GetDirectoryName(path));
        }

        try
        {
            File.WriteAllBytes(path, imageBytes);
            Debug.Log("Saved Data to: " + path.Replace("/", "\\"));
        }
        catch (Exception e)
        {
            Debug.LogWarning("Failed To Save Data to: " + path.Replace("/", "\\"));
            Debug.LogWarning("Error: " + e.Message);
        }
    }

Method to load stored images as a texture and update plane materials.

private void setLayerTexture(string layerName)
    {
        Debug.Log("LOOKING FOR PLANES GAMEOBJECTS");
        GameObject[] planes = GameObject.FindGameObjectsWithTag("MapTerrain");
       
        Debug.Log("ENCONTRADOS " + planes.Length + "planos");
       
        byte[] imageBytes;
        Texture2D texture;

        for (int i = 0; i < planes.Length; i++)
        {
            //Debug.Log("CARGANDO IMAGEN");
            Debug.Log("ACTUALIZANDO PLANO: " + planes[i].name);

            string subLayer = planes[i].name;
            char imageIndex = subLayer[subLayer.Length - 1];

            imageBytes = downloader.loadImage(savePath + layerName + "_" + imageIndex + ".jpg");

            texture = new Texture2D(2048, 2048);
            texture.LoadImage(imageBytes);
            planes[i].GetComponent<MeshRenderer>().material.SetTexture("_MainTex", texture);

            Debug.Log("PLANES UPDATED ");
        }
       
    }

Wait for the download to finish without error before you try to do anything with the images.