Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Resolved (UnityWebRequest) Unity freezes when use UnityWebRequestTexture

Discussion in 'Scripting' started by marck_ozz, Dec 12, 2020.

  1. marck_ozz

    marck_ozz

    Joined:
    Nov 30, 2018
    Posts:
    107
    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:

    Code (CSharp):
    1. IEnumerator GetBytes(string path, string ext)
    2.     {
    3.         UnityWebRequest.ClearCookieCache();
    4.         //writesuccess = false;
    5.  
    6.         HashSet<string> set = new HashSet<string>() { ".png", ".jpg", ".jpeg", ".bmp" };
    7.         if (set.Contains(ext))
    8.         {
    9.             www = UnityWebRequestTexture.GetTexture("file://" + path);
    10.  
    11.             DownloadHandlerTexture texDl = new DownloadHandlerTexture(true);
    12.             www.downloadHandler = texDl;
    13.             //yield return www.SendWebRequest();
    14.  
    15.             www.SendWebRequest();
    16.             while (!www.isDone)
    17.             {
    18.                 Debug.Log(www.downloadProgress);
    19.                 //yield return null;
    20.             }
    21.  
    22.             yield return new WaitUntil(() => www.downloadHandler.isDone);
    23.             Debug.Log("Imagen descargada exitosamente");
    24.             //while (!www.downloadHandler.isDone)
    25.             //{
    26.             //    Debug.Log("Coping File");
    27.             //    yield return null;
    28.             //}
    29.  
    30.             if (www.isNetworkError || www.isHttpError)
    31.             {
    32.                 Debug.Log(www.error);
    33.             }
    34.             else
    35.             {
    36.                 //image.texture = DownloadHandlerTexture.GetContent(www);
    37.                 results = www.downloadHandler.data;
    38.                 resultImgOK = true;
    39.                 Debug.Log(results.Length);
    40.             }
    41.         }
    42.         else
    43.         {
    44.             www = UnityWebRequest.Get("file://" + path);
    45.             //yield return www.SendWebRequest();
    46.  
    47.             www.SendWebRequest();
    48.             while (!www.isDone)
    49.             {
    50.                 Debug.Log(www.downloadProgress);
    51.                 //yield return null;
    52.             }
    53.  
    54.             Debug.Log(www.isDone);
    55.             yield return new WaitUntil(() => www.downloadHandler.isDone);
    56.             Debug.Log("Archivo descargado exitosamente");
    57.             //while (!www.downloadHandler.isDone)
    58.             //{
    59.             //    Debug.Log("Coping File");
    60.             //    yield return null;
    61.             //}  
    62.  
    63.             if (www.isNetworkError || www.isHttpError)
    64.             {
    65.                 Debug.Log(www.error);
    66.                 //writesuccess = false;
    67.             }
    68.             else
    69.             {
    70.                 results = www.downloadHandler.data;              
    71.                 //writesuccess = true;
    72.                 if (lastPath)
    73.                     resultGLTFOK = true;
    74.                 Debug.Log(results.Length);
    75.             }
    76.         }
    77.     }
    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!!.
     
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    Unity coroutines 101: Coroutines run on the main Unity engine thread. When you yield, you give Unity permission to do other stuff until <whatever>. 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.
     
  3. marck_ozz

    marck_ozz

    Joined:
    Nov 30, 2018
    Posts:
    107
    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.

    Code (CSharp):
    1. if (multy)
    2.         {
    3.             _path = "";
    4.             foreach (var p in paths)
    5.             {
    6.                 _path = p;
    7.                 fileName = Path.GetFileName(_path);
    8.                 StartCoroutine(WriteFile(_path, fileName));
    9.                 Debug.Log(_path);
    10.                 result = true;
    11.             }
    12.      
    13.  
    14.         resultOK = result;
    15.         return;
    16.     }
    17.  
    18.     IEnumerator WriteFile(string path, string fileName)
    19.     {
    20.         string ext;
    21.  
    22.         www = new WWW("file://" + path);
    23.         writePath = Path.Combine(Application.persistentDataPath, fileName);
    24.         System.IO.File.WriteAllBytes(writePath, www.bytes);
    25.  
    26.         ext = Path.GetExtension(fileName);
    27.         if(ext == ".txt" || ext == ".png")
    28.         {
    29.             //_pathObj = _path;
    30.             writePathObj = writePath;
    31.         }
    32.  
    33.         yield return new WaitUntil(() => File.Exists(writePath));
    34.     }

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