unity-game-engineimagedownload

Unity Engine freezes when trying to download an image from URL


I am writing a Pokemon TCG application, and I need to obtain card images at runtime from URLs (such as https://images.pokemontcg.io/bw1/1.png) in order to use them in sprite renderers. This must be done at runtime, because I won't know in advance which card images I will need.

To test my functions I used the url and a legacy button calling the LoadSprite funtion and a SpriteRenderer. But, when calling following function, the unity editor froze completely.

    [SerializeField] private SpriteRenderer card;
    [SerializeField] private string url;
 public void LoadSprite()
    {
        GenerateCard setCardSprite = new GenerateCard();
        setCardSprite.SetImage(card,url);
    }

The GenerateCard class (unfinished):

public class GenerateCard
{
    public void SetImage(SpriteRenderer card, string url)
    {
        Task<Texture2D> textureTask = DownloadImages.GetRemoteTexture(url);

        Texture2D cardimage = textureTask.Result;

        Rect rec = new Rect(0, 0, cardimage.width, cardimage.height);

        Sprite.Create(cardimage, rec, new Vector2(0, 0), 1);

        card.sprite = Sprite.Create(cardimage, rec, new Vector2(0, 0), .01f);
    }
}

I got the DownloadImages class with the GetRemoteTexture function from this StackOverflow question.

I tried using Debug.Log to find out which line causes the freeze, but nothing gets sent to the console. I also replaced (request.isNetworkError || request.isHttpError) with the newer (www.result == UnityWebRequest.Result.ConnectionError || www.result == UnityWebRequest.Result.ProtocolError):

public class DownloadImages
{

    public static async Task<Texture2D> GetRemoteTexture(string url)
    {
        Debug.Log("function was called");
        using (UnityWebRequest www = UnityWebRequestTexture.GetTexture(url))
        {
            // begin request:
            Debug.Log("begins request");
            var asyncOp = www.SendWebRequest();

            // await until it's done: 
            Debug.Log("start waiting");
            while (asyncOp.isDone == false)
                await Task.Delay(1000 / 30);//30 hertz
            Debug.Log("finished waiting");
            // read results:
            if (www.result == UnityWebRequest.Result.ConnectionError || www.result == UnityWebRequest.Result.ProtocolError)
            // if( www.result!=UnityWebRequest.Result.Success )// for Unity >= 2020.1
            {
                // log error:
                #if DEBUG
                Debug.Log($"{www.error}, URL:{www.url}");
                #endif

                // nothing to return on error:
                return null;
            }
            else
            {
                // return valid results:
                Debug.Log("Texture downloaded");
                return DownloadHandlerTexture.GetContent(www);
            }
        }
    }
}

I hope somebody knows why unity freezes and Thank You


Solution

  • I got it working by using a Coroutine. The Sprite is very big and needs to be scaled down but it gets downloaded correctly.

    public IEnumerator DownloadImage(string MediaUrl, SpriteRenderer card)
        {
            Texture2D cardimage = null;
            UnityWebRequest request = UnityWebRequestTexture.GetTexture(MediaUrl);
            yield return request.SendWebRequest();
            if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
                Debug.Log(request.error);
            else
                cardimage = ((DownloadHandlerTexture)request.downloadHandler).texture;
            if (cardimage == null)
            {
                Debug.Log("cardimage is null");
            }
            Rect rec = new Rect(0, 0, cardimage.width, cardimage.height);
            Sprite sprite = Sprite.Create(cardimage, rec, new Vector2(0, 0), 1);
            card.sprite = sprite;
        }