(UnityWebRequest) Unity freezes when use UnityWebRequestTexture

Hello all.

After upgrading the use of “WWW” to “UnityWebRequest” (wich is annoying btw) I’m running into a “problem” (not much a problem) here.

I use this rutine of UnityWebRequest for download texts and Images Like this:

IEnumerator GetBytes(string path, string ext)
    {
        UnityWebRequest.ClearCookieCache();
        //writesuccess = false;

        HashSet<string> set = new HashSet<string>() { ".png", ".jpg", ".jpeg", ".bmp" };
        if (set.Contains(ext))
        {
            www = UnityWebRequestTexture.GetTexture("file://" + path);

            DownloadHandlerTexture texDl = new DownloadHandlerTexture(true);
            www.downloadHandler = texDl;
            //yield return www.SendWebRequest();

            www.SendWebRequest();
            while (!www.isDone)
            {
                Debug.Log(www.downloadProgress);
                //yield return null;
            }

            yield return new WaitUntil(() => www.downloadHandler.isDone);
            Debug.Log("Imagen descargada exitosamente");
            //while (!www.downloadHandler.isDone)
            //{
            //    Debug.Log("Coping File");
            //    yield return null;
            //}

            if (www.isNetworkError || www.isHttpError)
            {
                Debug.Log(www.error);
            }
            else
            {
                //image.texture = DownloadHandlerTexture.GetContent(www);
                results = www.downloadHandler.data;
                resultImgOK = true;
                Debug.Log(results.Length);
            }
        }
        else
        {
            www = UnityWebRequest.Get("file://" + path);
            //yield return www.SendWebRequest();

            www.SendWebRequest();
            while (!www.isDone)
            {
                Debug.Log(www.downloadProgress);
                //yield return null;
            }

            Debug.Log(www.isDone);
            yield return new WaitUntil(() => www.downloadHandler.isDone);
            Debug.Log("Archivo descargado exitosamente");
            //while (!www.downloadHandler.isDone)
            //{
            //    Debug.Log("Coping File");
            //    yield return null;
            //}  

            if (www.isNetworkError || www.isHttpError)
            {
                Debug.Log(www.error);
                //writesuccess = false;
            }
            else
            {
                results = www.downloadHandler.data;               
                //writesuccess = true;
                if (lastPath)
                    resultGLTFOK = true;
                Debug.Log(results.Length);
            }
        }
    }

Downloading texts works fine,the problem is that when in comes the time to download a image Unity freezes at all (with no bugs) and I have to force the close.

BUT!! if I change the “www.SendWebRequest();” line by “yield return www.SendWebRequest();” (commented in this code) everything works fine. I don’t use the last because I want to handle and monitor the download proccess in case of large images.

So I can use the “yield return www.SendWebRequest()” but I want to know what causes Unity yo freeze with “www.SendWebRequest();

Thank you in advance.

Saludos!!.

Unity coroutines 101: Coroutines run on the main Unity engine thread. When you yield, you give Unity permission to do other stuff until . When you don’t yield, Unity has to wait for you, because Unity can only do one thing at a time and right now you are it.

If you uncommented the “yield return null” inside of the while loop on lines 16-20, then you’d be giving Unity permission to do one more frame each time you check and find that the download isn’t done yet. But since you commented that line out, you aren’t giving Unity permission to do anything, so it has to just sit there and wait until your loop ends.

4 Likes

Thank you so much man that solved the problem. I just thought that the “WaitUntil” yield was doing the same that “return null”. It also solved another problem that I was having with downloading multiple files.

But now all the files are saved with the same information than the first file downloaded. I mean this:

If I downloadad:
pic01.png (105kb)
pic02.png (500kb)
text01.txt (25kb)

I have this in my local path:
pic01.png (105kb)
pic02.png (105kb)
text01.txt (105kb)

And the pic02 is the same that pic01 and the .txt file has what I thing is the information of pic01. I thougt the “UnityWebRequest.ClearCookieCache();” solves this but not, even try with “www.downloadHandler.Dispose();” but that trigger an error because the consecutive dowload still tries to use that info.

I had all that solved with the old “WWW” API like on the next code but this “UnityWebRequest” is a little confusing.

if (multy)
        {
            _path = "";
            foreach (var p in paths)
            {
                _path = p;
                fileName = Path.GetFileName(_path);
                StartCoroutine(WriteFile(_path, fileName));
                Debug.Log(_path);
                result = true;
            }
      

        resultOK = result;
        return;
    }

    IEnumerator WriteFile(string path, string fileName)
    {
        string ext;

        www = new WWW("file://" + path);
        writePath = Path.Combine(Application.persistentDataPath, fileName);
        System.IO.File.WriteAllBytes(writePath, www.bytes);

        ext = Path.GetExtension(fileName);
        if(ext == ".txt" || ext == ".png")
        {
            //_pathObj = _path;
            writePathObj = writePath;
        }

        yield return new WaitUntil(() => File.Exists(writePath));
    }

I’ll mark this thread as solved since my original question was answered and maybe ask for this in another tread.