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