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 ");
}
}