Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Runtime loading textures sometime result in gray texture

Discussion in 'General Graphics' started by jiraphatK, Sep 25, 2020.

  1. jiraphatK

    jiraphatK

    Joined:
    Sep 29, 2018
    Posts:
    293
    Have anyone ever encounter this problem?
    Loading texture during runtime sometime result in this gray texture like it's not fully load yet
    Unity 2019.3.3f1 built in render pipeline.
    I download texture using UnityDownloadHandlerFile to cache it in my maching then use UnityWebRequestTexture to load from the save path
    example

     

    Attached Files:

    Last edited: Sep 25, 2020
  2. cholleme

    cholleme

    Unity Technologies

    Joined:
    Apr 23, 2019
    Posts:
    31
    So you do a UnityDownloadHandlerFile to a local location on disc and then use a file: url passed to UnityWebRequestTexture to load that texture again?

    It looks like the texture gets decoded on a partially written file. Are you waiting for the async results to finish between each step? Do the network transfers finish without errors?

    Can you maybe share a small script example of your set-up?
     
  3. jiraphatK

    jiraphatK

    Joined:
    Sep 29, 2018
    Posts:
    293
    Oh, that's might be the case. Basically the flow is like this
    I have an image URL that I need to use at 2 places, say, a profile picture, and at some other place. I start the coroutine to load the image from this URL at the same time-in the start method.

    I use this function to download image

    Code (CSharp):
    1. public IEnumerator LoadImageAndCache(string url, string savePath, Action<Texture> OnComplete)
    2.     {
    3.         if (!File.Exists(savePath))
    4.         {
    5.             //Debug.Log(savePath + " don't exist in local path, try loading...");
    6.             UnityWebRequest uwr = new UnityWebRequest(url);
    7.             uwr.method = UnityWebRequest.kHttpVerbGET;
    8.             uwr.useHttpContinue = false;
    9.             DownloadHandlerFile savedFile = new DownloadHandlerFile(savePath);
    10.             savedFile.removeFileOnAbort = true;
    11.             uwr.downloadHandler = savedFile;
    12.             savedFile.removeFileOnAbort = true;
    13.             yield return uwr.SendWebRequest();
    14.  
    15.             if (uwr.isNetworkError || uwr.isHttpError)
    16.             {
    17.                 Debug.Log(uwr.error);
    18.             }
    19.             else
    20.             {
    21.                 Debug.Log(savePath + " Save successful, try loading from local");
    22.                 yield return StartCoroutine(LoadImageFromLocal(url, savePath, OnComplete));
    23.             }
    24.         }
    25.         else
    26.         {
    27.             yield return StartCoroutine(LoadImageFromLocal(url, savePath, OnComplete));
    28.         }
    29.     }
    and this is LoadFromLocal. As you can see, I tried prevent loading from file that was being written. But it seems to not work?

    Code (CSharp):
    1. private IEnumerator LoadImageFromLocal(string url, string localPath, Action<Texture> OnComplete)
    2.     {
    3.         FileInfo fileInfo = new FileInfo(localPath);
    4.         if (IsFileLocked(fileInfo))
    5.         {
    6.             Debug.Log("File is being written, load from web instead");
    7.             yield return StartCoroutine(LoadImageFromWeb(url, OnComplete));
    8.         }
    9.         else //file is not being written
    10.         {
    11.             UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(localPath);
    12.  
    13.             uwr.uri = new Uri(uwr.uri.AbsoluteUri.Replace("http://localhost", "file://"));
    14.             uwr.url = uwr.url.Replace("http://localhost", "file://");
    15.  
    16.             yield return uwr.SendWebRequest();
    17.  
    18.             if (uwr.isNetworkError || uwr.isHttpError)
    19.             {
    20.                 Debug.Log("Error loading from local, load by url instead....");
    21.                 //error loading from local, try loading through web instead
    22.                 yield return StartCoroutine(LoadImageFromWeb(url, OnComplete));
    23.             }
    24.             else
    25.             {
    26.                 Texture texture = DownloadHandlerTexture.GetContent(uwr);
    27.                 OnComplete(texture);
    28.             }
    29.         }
    30.     }
    here's the code to check if the file is being written

    Code (CSharp):
    1. bool IsFileLocked(FileInfo file)
    2.     {
    3.         FileStream stream = null;
    4.  
    5.         try
    6.         {
    7.             stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
    8.         }
    9.         catch (IOException)
    10.         {
    11.             return true;
    12.         }
    13.         finally
    14.         {
    15.             if (stream != null)
    16.                 stream.Close();
    17.         }
    18.  
    19.         //file is not locked
    20.         return false;
    21.     }
     
    Last edited: Sep 25, 2020